分组添加封面配置

pull/1222/head
gedoor 3 years ago
parent bb7df5b804
commit 2b6430a81f
  1. 4
      app/src/main/assets/updateLog.md
  2. 10
      app/src/main/java/io/legado/app/data/AppDatabase.kt
  3. 2
      app/src/main/java/io/legado/app/data/entities/BookGroup.kt
  4. 55
      app/src/main/java/io/legado/app/ui/book/group/GroupEdit.kt
  5. 110
      app/src/main/java/io/legado/app/ui/book/group/GroupEditDialog.kt
  6. 26
      app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt
  7. 45
      app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt
  8. 23
      app/src/main/java/io/legado/app/ui/book/group/GroupViewModel.kt
  9. 4
      app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt
  10. 5
      app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt
  11. 89
      app/src/main/res/layout/dialog_book_group_edit.xml

@ -12,6 +12,10 @@
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
* 关于最近版本有时候界面没有数据的问题是因为把LiveData组件换成了谷歌推荐的Flow组件导致的问题,正在查找解决办法
**2021/08/09**
1. 修复选择文字不能选择单个文字的bug
**2021/08/08**
1. 背景图片添加模糊设置

@ -24,7 +24,7 @@ val appDb by lazy {
RssSource::class, Bookmark::class, RssArticle::class, RssReadRecord::class,
RssStar::class, TxtTocRule::class, ReadRecord::class, HttpTTS::class, Cache::class,
RuleSub::class],
version = 33,
version = 34,
exportSchema = true
)
abstract class AppDatabase : RoomDatabase() {
@ -60,7 +60,7 @@ abstract class AppDatabase : RoomDatabase() {
migration_19_20, migration_20_21, migration_21_22, migration_22_23,
migration_23_24, migration_24_25, migration_25_26, migration_26_27,
migration_27_28, migration_28_29, migration_29_30, migration_30_31,
migration_31_32, migration_32_33
migration_31_32, migration_32_33, migration_33_34
)
.allowMainThreadQueries()
.addCallback(dbCallback)
@ -331,6 +331,12 @@ abstract class AppDatabase : RoomDatabase() {
)
}
}
private val migration_33_34 = object : Migration(33, 34) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `book_groups` ADD `cover` TEXT")
}
}
}
}

@ -14,6 +14,7 @@ data class BookGroup(
@PrimaryKey
val groupId: Long = 0b1,
var groupName: String,
var cover: String? = null,
var order: Int = 0,
var show: Boolean = true
) : Parcelable {
@ -36,6 +37,7 @@ data class BookGroup(
if (other is BookGroup) {
return other.groupId == groupId
&& other.groupName == groupName
&& other.cover == cover
&& other.order == order
&& other.show == show
}

@ -1,55 +0,0 @@
package io.legado.app.ui.book.group
import android.content.Context
import android.view.LayoutInflater
import io.legado.app.R
import io.legado.app.data.appDb
import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.coroutine.Coroutine
import io.legado.app.lib.dialogs.alert
import io.legado.app.utils.requestInputMethod
object GroupEdit {
fun show(context: Context, layoutInflater: LayoutInflater, bookGroup: BookGroup) = context.run {
alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
editView.setText(bookGroup.groupName)
}
if (bookGroup.groupId >= 0) {
neutralButton(R.string.delete) {
deleteGroup(context, bookGroup)
}
}
customView { alertBinding.root }
yesButton {
alertBinding.editView.text?.toString()?.let {
bookGroup.groupName = it
Coroutine.async {
appDb.bookGroupDao.update(bookGroup)
}
}
}
noButton()
}.show().requestInputMethod()
}
private fun deleteGroup(context: Context, bookGroup: BookGroup) = context.run {
alert(R.string.delete, R.string.sure_del) {
okButton {
Coroutine.async {
appDb.bookGroupDao.delete(bookGroup)
val books = appDb.bookDao.getBooksByGroup(bookGroup.groupId)
books.forEach {
it.group = it.group - bookGroup.groupId
}
appDb.bookDao.update(*books.toTypedArray())
}
}
noButton()
}.show()
}
}

@ -0,0 +1,110 @@
package io.legado.app.ui.book.group
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.DialogBookGroupEditBinding
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.primaryColor
import io.legado.app.utils.gone
import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
import splitties.views.onClick
class GroupEditDialog : BaseDialogFragment() {
companion object {
fun start(fragmentManager: FragmentManager, bookGroup: BookGroup? = null) {
GroupEditDialog().apply {
arguments = Bundle().apply {
putParcelable("group", bookGroup)
}
}.show(fragmentManager, "bookGroupEdit")
}
}
private val binding by viewBinding(DialogBookGroupEditBinding::bind)
private val viewModel by viewModels<GroupViewModel>()
private var bookGroup: BookGroup? = null
override fun onStart() {
super.onStart()
val dm = requireActivity().windowSize
dialog?.window?.setLayout(
(dm.widthPixels * 0.9).toInt(),
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.dialog_book_group_edit, container)
}
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
binding.toolBar.setBackgroundColor(primaryColor)
bookGroup = arguments?.getParcelable("group")
bookGroup?.let {
binding.tieGroupName.setText(it.groupName)
binding.ivCover.load(it.cover)
} ?: let {
binding.toolBar.title = getString(R.string.add_group)
binding.btnDelete.gone()
}
binding.run {
btnCancel.onClick {
dismiss()
}
btnOk.onClick {
val groupName = tieGroupName.text?.toString()
if (groupName.isNullOrEmpty()) {
toastOnUi("分组名称不能为空")
} else {
bookGroup?.let {
it.groupName = groupName
it.cover = binding.ivCover.path
viewModel.upGroup(it) {
dismiss()
}
} ?: let {
viewModel.addGroup(groupName, binding.ivCover.path) {
dismiss()
}
}
}
}
btnDelete.onClick {
deleteGroup {
bookGroup?.let {
viewModel.delGroup(it) {
dismiss()
}
}
}
}
}
}
private fun deleteGroup(ok: () -> Unit) {
alert(R.string.delete, R.string.sure_del) {
okButton {
ok.invoke()
}
noButton()
}.show()
}
}

@ -1,6 +1,5 @@
package io.legado.app.ui.book.group
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
@ -18,17 +17,14 @@ import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.data.appDb
import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemBookGroupManageBinding
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.accentColor
import io.legado.app.lib.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.applyTint
import io.legado.app.utils.requestInputMethod
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.visible
import io.legado.app.utils.windowSize
@ -94,29 +90,11 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onMenuItemClick(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.menu_add -> addGroup()
R.id.menu_add -> GroupEditDialog.start(childFragmentManager)
}
return true
}
@SuppressLint("InflateParams")
private fun addGroup() {
alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
}
customView { alertBinding.root }
yesButton {
alertBinding.editView.text?.toString()?.let {
if (it.isNotBlank()) {
viewModel.addGroup(it)
}
}
}
noButton()
}.show().requestInputMethod()
}
private inner class GroupAdapter(context: Context) :
RecyclerAdapter<BookGroup, ItemBookGroupManageBinding>(context),
ItemTouchCallback.Callback {
@ -144,7 +122,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
binding.run {
tvEdit.setOnClickListener {
getItem(holder.layoutPosition)?.let { bookGroup ->
GroupEdit.show(context, layoutInflater, bookGroup)
GroupEditDialog.start(childFragmentManager, bookGroup)
}
}
swShow.setOnCheckedChangeListener { buttonView, isChecked ->

@ -1,6 +1,5 @@
package io.legado.app.ui.book.group
import android.annotation.SuppressLint
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
@ -20,16 +19,13 @@ import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.data.appDb
import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.DialogBookGroupPickerBinding
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.ItemGroupSelectBinding
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.accentColor
import io.legado.app.lib.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.applyTint
import io.legado.app.utils.requestInputMethod
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
import kotlinx.coroutines.flow.collect
@ -116,46 +112,11 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onMenuItemClick(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.menu_add -> addGroup()
R.id.menu_add -> GroupEditDialog.start(childFragmentManager)
}
return true
}
@SuppressLint("InflateParams")
private fun addGroup() {
alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
}
customView { alertBinding.root }
yesButton {
alertBinding.editView.text?.toString()?.let {
if (it.isNotBlank()) {
viewModel.addGroup(it)
}
}
}
noButton()
}.show().requestInputMethod()
}
@SuppressLint("InflateParams")
private fun editGroup(bookGroup: BookGroup) {
alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
editView.setText(bookGroup.groupName)
}
customView { alertBinding.root }
yesButton {
alertBinding.editView.text?.toString()?.let {
viewModel.upGroup(bookGroup.copy(groupName = it))
}
}
noButton()
}.show().requestInputMethod()
}
private inner class GroupAdapter(context: Context) :
RecyclerAdapter<BookGroup, ItemGroupSelectBinding>(context),
ItemTouchCallback.Callback {
@ -192,7 +153,9 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
}
}
}
tvEdit.setOnClickListener { getItem(holder.layoutPosition)?.let { editGroup(it) } }
tvEdit.setOnClickListener {
GroupEditDialog.start(childFragmentManager, getItem(holder.layoutPosition))
}
}
}

@ -7,7 +7,15 @@ import io.legado.app.data.entities.BookGroup
class GroupViewModel(application: Application) : BaseViewModel(application) {
fun addGroup(groupName: String) {
fun upGroup(vararg bookGroup: BookGroup, finally: (() -> Unit)? = null) {
execute {
appDb.bookGroupDao.update(*bookGroup)
}.onFinally {
finally?.invoke()
}
}
fun addGroup(groupName: String, cover: String?, finally: () -> Unit) {
execute {
var id = 1L
val idsSum = appDb.bookGroupDao.idsSum
@ -17,19 +25,16 @@ class GroupViewModel(application: Application) : BaseViewModel(application) {
val bookGroup = BookGroup(
groupId = id,
groupName = groupName,
cover = cover,
order = appDb.bookGroupDao.maxOrder.plus(1)
)
appDb.bookGroupDao.insert(bookGroup)
}.onFinally {
finally()
}
}
fun upGroup(vararg bookGroup: BookGroup) {
execute {
appDb.bookGroupDao.update(*bookGroup)
}
}
fun delGroup(vararg bookGroup: BookGroup) {
fun delGroup(vararg bookGroup: BookGroup, finally: () -> Unit) {
execute {
appDb.bookGroupDao.delete(*bookGroup)
bookGroup.forEach { group ->
@ -39,6 +44,8 @@ class GroupViewModel(application: Application) : BaseViewModel(application) {
}
appDb.bookDao.update(*books.toTypedArray())
}
}.onFinally {
finally()
}
}

@ -22,7 +22,7 @@ import io.legado.app.help.AppConfig
import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.book.audio.AudioPlayActivity
import io.legado.app.ui.book.group.GroupEdit
import io.legado.app.ui.book.group.GroupEditDialog
import io.legado.app.ui.book.info.BookInfoActivity
import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.book.search.SearchActivity
@ -190,7 +190,7 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1),
putExtra("name", item.name)
putExtra("author", item.author)
}
is BookGroup -> GroupEdit.show(requireContext(), layoutInflater, item)
is BookGroup -> GroupEditDialog.start(childFragmentManager, item)
}
}

@ -30,6 +30,8 @@ class CoverImageView @JvmOverloads constructor(
) {
internal var width: Float = 0.toFloat()
internal var height: Float = 0.toFloat()
var path: String? = null
private set
private var nameHeight = 0f
private var authorHeight = 0f
private val namePaint by lazy {
@ -131,7 +133,8 @@ class CoverImageView @JvmOverloads constructor(
}
}
fun load(path: String?, name: String?, author: String?) {
fun load(path: String?, name: String? = null, author: String? = null) {
this.path = path
setText(name, author)
if (AppConfig.useDefaultCover) {
ImageLoader.load(context, defaultDrawable)

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background_menu">
<androidx.appcompat.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background_menu"
android:elevation="5dp"
android:theme="?attr/actionBarStyle"
app:displayHomeAsUp="false"
app:fitStatusBar="false"
app:layout_constraintTop_toTopOf="parent"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:title="@string/group_edit"
app:titleTextAppearance="@style/ToolbarTitle" />
<io.legado.app.ui.widget.image.CoverImageView
android:id="@+id/iv_cover"
android:layout_width="90dp"
android:layout_height="126dp"
android:layout_margin="6dp"
android:contentDescription="@string/img_cover"
android:scaleType="centerCrop"
android:src="@drawable/image_cover_default"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tool_bar" />
<io.legado.app.ui.widget.text.TextInputLayout
android:id="@+id/til_group_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="6dp"
android:hint="@string/group_name"
app:layout_constraintLeft_toRightOf="@+id/iv_cover"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tool_bar"
app:layout_constraintBottom_toTopOf="@+id/btn_ok">
<io.legado.app.ui.widget.text.EditText
android:id="@+id/tie_group_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
tools:ignore="TouchTargetSizeCheck,SpeakableTextPresentCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>
<io.legado.app.ui.widget.text.AccentTextView
android:id="@+id/btn_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:layout_marginLeft="12dp"
android:text="@string/delete"
app:layout_constraintBottom_toBottomOf="@id/btn_ok"
app:layout_constraintLeft_toRightOf="@+id/iv_cover"
app:layout_constraintTop_toTopOf="@+id/btn_ok"
tools:ignore="RtlHardcoded" />
<io.legado.app.ui.widget.text.AccentTextView
android:id="@+id/btn_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:layout_marginRight="12dp"
android:text="@string/ok"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_group_name"
tools:ignore="RtlHardcoded" />
<io.legado.app.ui.widget.text.AccentTextView
android:id="@+id/btn_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:text="@string/cancel"
app:layout_constraintBottom_toBottomOf="@id/btn_ok"
app:layout_constraintRight_toLeftOf="@+id/btn_ok"
app:layout_constraintTop_toTopOf="@+id/btn_ok" />
</androidx.constraintlayout.widget.ConstraintLayout>
Loading…
Cancel
Save