viewBinding

pull/517/head
gedoor 5 years ago
parent 6852689604
commit 1225af46a4
  1. 60
      app/src/main/java/io/legado/app/base/adapter/CommonRecyclerAdapter.kt
  2. 12
      app/src/main/java/io/legado/app/base/adapter/ItemViewDelegate.kt
  3. 5
      app/src/main/java/io/legado/app/base/adapter/ItemViewHolder.kt
  4. 29
      app/src/main/java/io/legado/app/base/adapter/SimpleRecyclerAdapter.kt
  5. 9
      app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt
  6. 66
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceDialog.kt
  7. 4
      app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleActivity.kt
  8. 54
      app/src/main/java/io/legado/app/ui/association/ImportRssSourceDialog.kt
  9. 34
      app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookAdapter.kt
  10. 35
      app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt
  11. 24
      app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt
  12. 14
      app/src/main/java/io/legado/app/ui/book/changecover/CoverAdapter.kt
  13. 27
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceAdapter.kt
  14. 43
      app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt
  15. 3
      app/src/main/java/io/legado/app/ui/book/explore/ExploreShowActivity.kt
  16. 39
      app/src/main/java/io/legado/app/ui/book/explore/ExploreShowAdapter.kt
  17. 76
      app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt
  18. 69
      app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt
  19. 21
      app/src/main/java/io/legado/app/ui/book/info/ChapterListAdapter.kt
  20. 49
      app/src/main/java/io/legado/app/ui/book/local/ImportBookAdapter.kt
  21. 45
      app/src/main/java/io/legado/app/ui/book/read/TextActionMenu.kt
  22. 45
      app/src/main/java/io/legado/app/ui/book/read/config/AutoReadDialog.kt
  23. 22
      app/src/main/java/io/legado/app/ui/book/read/config/BgAdapter.kt
  24. 64
      app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt
  25. 39
      app/src/main/java/io/legado/app/ui/book/read/config/ClickActionConfigDialog.kt
  26. 61
      app/src/main/java/io/legado/app/ui/book/read/config/PaddingConfigDialog.kt
  27. 27
      app/src/main/java/io/legado/app/ui/book/read/config/PageKeyDialog.kt
  28. 102
      app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt
  29. 123
      app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt
  30. 96
      app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt
  31. 91
      app/src/main/java/io/legado/app/ui/book/read/config/TipConfigDialog.kt
  32. 110
      app/src/main/java/io/legado/app/ui/book/read/config/TocRegexDialog.kt
  33. 18
      app/src/main/java/io/legado/app/ui/book/search/BookAdapter.kt
  34. 18
      app/src/main/java/io/legado/app/ui/book/search/HistoryKeyAdapter.kt
  35. 83
      app/src/main/java/io/legado/app/ui/book/search/SearchAdapter.kt
  36. 19
      app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentAdapter.kt
  37. 28
      app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugAdapter.kt
  38. 15
      app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditAdapter.kt
  39. 49
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt
  40. 75
      app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt
  41. 16
      app/src/main/java/io/legado/app/ui/book/toc/BookmarkAdapter.kt
  42. 30
      app/src/main/java/io/legado/app/ui/book/toc/BookmarkFragment.kt
  43. 48
      app/src/main/java/io/legado/app/ui/book/toc/ChapterListAdapter.kt
  44. 35
      app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt
  45. 15
      app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt
  46. 13
      app/src/main/java/io/legado/app/ui/config/ThemeConfigFragment.kt
  47. 53
      app/src/main/java/io/legado/app/ui/config/ThemeListDialog.kt
  48. 73
      app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt
  49. 5
      app/src/main/java/io/legado/app/ui/main/bookshelf/books/BaseBooksAdapter.kt
  50. 57
      app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksAdapterGrid.kt
  51. 63
      app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksAdapterList.kt
  52. 34
      app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt
  53. 62
      app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt
  54. 41
      app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt
  55. 7
      app/src/main/java/io/legado/app/ui/main/my/MyFragment.kt
  56. 15
      app/src/main/java/io/legado/app/ui/main/rss/RssAdapter.kt
  57. 14
      app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt
  58. 28
      app/src/main/java/io/legado/app/ui/widget/recycler/LoadMoreView.kt
  59. 58
      app/src/main/java/io/legado/app/utils/viewbindingdelegate/DialogFragmentViewBindings.kt
  60. 1
      app/src/main/res/layout/dialog_auto_read.xml

@ -3,11 +3,12 @@ package io.legado.app.base.adapter
import android.content.Context import android.content.Context
import android.util.SparseArray import android.util.SparseArray
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import java.lang.reflect.ParameterizedType
import java.util.* import java.util.*
/** /**
@ -16,26 +17,26 @@ import java.util.*
* 通用的adapter 可添加headerfooter以及不同类型item * 通用的adapter 可添加headerfooter以及不同类型item
*/ */
@Suppress("unused", "MemberVisibilityCanBePrivate") @Suppress("unused", "MemberVisibilityCanBePrivate")
abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val context: Context) :
RecyclerView.Adapter<ItemViewHolder>() { RecyclerView.Adapter<ItemViewHolder>() {
constructor(context: Context, vararg delegates: ItemViewDelegate<ITEM>) : this(context) { constructor(context: Context, vararg delegates: ItemViewDelegate<ITEM, VB>) : this(context) {
addItemViewDelegates(*delegates) addItemViewDelegates(*delegates)
} }
constructor( constructor(
context: Context, context: Context,
vararg delegates: Pair<Int, ItemViewDelegate<ITEM>> vararg delegates: Pair<Int, ItemViewDelegate<ITEM, VB>>
) : this(context) { ) : this(context) {
addItemViewDelegates(*delegates) addItemViewDelegates(*delegates)
} }
private val inflater: LayoutInflater = LayoutInflater.from(context) val inflater: LayoutInflater = LayoutInflater.from(context)
private var headerItems: SparseArray<View>? = null private var headerItems: SparseArray<ViewBinding>? = null
private var footerItems: SparseArray<View>? = null private var footerItems: SparseArray<ViewBinding>? = null
private val itemDelegates: HashMap<Int, ItemViewDelegate<ITEM>> = hashMapOf() private val itemDelegates: HashMap<Int, ItemViewDelegate<ITEM, VB>> = hashMapOf()
private val items: MutableList<ITEM> = mutableListOf() private val items: MutableList<ITEM> = mutableListOf()
private val lock = Object() private val lock = Object()
@ -58,26 +59,29 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
recyclerView.adapter = this recyclerView.adapter = this
} }
fun <DELEGATE : ItemViewDelegate<ITEM>> addItemViewDelegate(viewType: Int, delegate: DELEGATE) { fun <DELEGATE : ItemViewDelegate<ITEM, VB>> addItemViewDelegate(
viewType: Int,
delegate: DELEGATE
) {
itemDelegates[viewType] = delegate itemDelegates[viewType] = delegate
} }
fun <DELEGATE : ItemViewDelegate<ITEM>> addItemViewDelegate(delegate: DELEGATE) { fun addItemViewDelegate(delegate: ItemViewDelegate<ITEM, VB>) {
itemDelegates[itemDelegates.size] = delegate itemDelegates[itemDelegates.size] = delegate
} }
fun <DELEGATE : ItemViewDelegate<ITEM>> addItemViewDelegates(vararg delegates: DELEGATE) { fun addItemViewDelegates(vararg delegates: ItemViewDelegate<ITEM, VB>) {
delegates.forEach { delegates.forEach {
addItemViewDelegate(it) addItemViewDelegate(it)
} }
} }
fun addItemViewDelegates(vararg delegates: Pair<Int, ItemViewDelegate<ITEM>>) = fun addItemViewDelegates(vararg delegates: Pair<Int, ItemViewDelegate<ITEM, VB>>) =
delegates.forEach { delegates.forEach {
addItemViewDelegate(it.first, it.second) addItemViewDelegate(it.first, it.second)
} }
fun addHeaderView(header: View) { fun addHeaderView(header: ViewBinding) {
synchronized(lock) { synchronized(lock) {
if (headerItems == null) { if (headerItems == null) {
headerItems = SparseArray() headerItems = SparseArray()
@ -90,7 +94,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
} }
} }
fun addFooterView(footer: View) = fun addFooterView(footer: ViewBinding) =
synchronized(lock) { synchronized(lock) {
if (footerItems == null) { if (footerItems == null) {
footerItems = SparseArray() footerItems = SparseArray()
@ -103,7 +107,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
} }
fun removeHeaderView(header: View) = fun removeHeaderView(header: ViewBinding) =
synchronized(lock) { synchronized(lock) {
headerItems?.let { headerItems?.let {
val index = it.indexOfValue(header) val index = it.indexOfValue(header)
@ -114,7 +118,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
} }
} }
fun removeFooterView(footer: View) = fun removeFooterView(footer: ViewBinding) =
synchronized(lock) { synchronized(lock) {
footerItems?.let { footerItems?.let {
val index = it.indexOfValue(footer) val index = it.indexOfValue(footer)
@ -309,16 +313,12 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
} }
else -> { else -> {
val holder = ItemViewHolder( //使用反射得到viewBinding的class
inflater.inflate( val holder = ItemViewHolder(getViewBinding(parent, viewType))
itemDelegates.getValue(viewType).layoutId,
parent,
false
)
)
@Suppress("UNCHECKED_CAST")
itemDelegates.getValue(viewType) itemDelegates.getValue(viewType)
.registerListener(holder) .registerListener(holder, (holder.binding as VB))
if (itemClickListener != null) { if (itemClickListener != null) {
holder.itemView.setOnClickListener { holder.itemView.setOnClickListener {
@ -340,8 +340,18 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
} }
} }
private fun getViewBinding(parent: ViewGroup, viewType: Int): ViewBinding {
//使用反射得到viewBinding的class
val type = javaClass.genericSuperclass as ParameterizedType
val aClass = type.actualTypeArguments[0] as Class<*>
val method = aClass.getDeclaredMethod("inflate", LayoutInflater::class.java)
@Suppress("UNCHECKED_CAST")
return method.invoke(null, inflater, parent, false) as VB
}
final override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {} final override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {}
@Suppress("UNCHECKED_CAST")
final override fun onBindViewHolder( final override fun onBindViewHolder(
holder: ItemViewHolder, holder: ItemViewHolder,
position: Int, position: Int,
@ -350,7 +360,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
if (!isHeader(holder.layoutPosition) && !isFooter(holder.layoutPosition)) { if (!isHeader(holder.layoutPosition) && !isFooter(holder.layoutPosition)) {
getItem(holder.layoutPosition - getHeaderCount())?.let { getItem(holder.layoutPosition - getHeaderCount())?.let {
itemDelegates.getValue(getItemViewType(holder.layoutPosition)) itemDelegates.getValue(getItemViewType(holder.layoutPosition))
.convert(holder, it, payloads) .convert(holder, (holder.binding as VB), it, payloads)
} }
} }
} }

@ -1,25 +1,31 @@
package io.legado.app.base.adapter package io.legado.app.base.adapter
import android.content.Context import android.content.Context
import androidx.viewbinding.ViewBinding
/** /**
* Created by Invincible on 2017/11/24. * Created by Invincible on 2017/11/24.
* *
* item代理 * item代理
*/ */
abstract class ItemViewDelegate<ITEM>(protected val context: Context, val layoutId: Int) { abstract class ItemViewDelegate<ITEM, VB : ViewBinding>(protected val context: Context) {
/** /**
* 如果使用了事件回调,回调里不要直接使用item,会出现不更新的问题, * 如果使用了事件回调,回调里不要直接使用item,会出现不更新的问题,
* 使用getItem(holder.layoutPosition)来获取item, * 使用getItem(holder.layoutPosition)来获取item,
* 或者使用registerListener(holder: ItemViewHolder, position: Int) * 或者使用registerListener(holder: ItemViewHolder, position: Int)
*/ */
abstract fun convert(holder: ItemViewHolder, item: ITEM, payloads: MutableList<Any>) abstract fun convert(
holder: ItemViewHolder,
binding: VB,
item: ITEM,
payloads: MutableList<Any>
)
/** /**
* 注册事件 * 注册事件
*/ */
abstract fun registerListener(holder: ItemViewHolder) abstract fun registerListener(holder: ItemViewHolder, binding: VB)
} }

@ -1,9 +1,10 @@
package io.legado.app.base.adapter package io.legado.app.base.adapter
import android.view.View
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
/** /**
* Created by Invincible on 2017/11/28. * Created by Invincible on 2017/11/28.
*/ */
class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) @Suppress("MemberVisibilityCanBePrivate")
class ItemViewHolder(val binding: ViewBinding) : RecyclerView.ViewHolder(binding.root)

@ -1,22 +1,28 @@
package io.legado.app.base.adapter package io.legado.app.base.adapter
import android.content.Context import android.content.Context
import androidx.viewbinding.ViewBinding
/** /**
* Created by Invincible on 2017/12/15. * Created by Invincible on 2017/12/15.
*/ */
abstract class SimpleRecyclerAdapter<ITEM>(context: Context, private val layoutId: Int) : abstract class SimpleRecyclerAdapter<ITEM, VB : ViewBinding>(context: Context) :
CommonRecyclerAdapter<ITEM>(context) { CommonRecyclerAdapter<ITEM, VB>(context) {
init { init {
addItemViewDelegate(object : ItemViewDelegate<ITEM>(context, layoutId) { addItemViewDelegate(object : ItemViewDelegate<ITEM, VB>(context) {
override fun convert(holder: ItemViewHolder, item: ITEM, payloads: MutableList<Any>) { override fun convert(
this@SimpleRecyclerAdapter.convert(holder, item, payloads) holder: ItemViewHolder,
binding: VB,
item: ITEM,
payloads: MutableList<Any>
) {
this@SimpleRecyclerAdapter.convert(holder, binding, item, payloads)
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: VB) {
this@SimpleRecyclerAdapter.registerListener(holder) this@SimpleRecyclerAdapter.registerListener(holder, binding)
} }
}) })
} }
@ -25,10 +31,15 @@ abstract class SimpleRecyclerAdapter<ITEM>(context: Context, private val layoutI
* 如果使用了事件回调,回调里不要直接使用item,会出现不更新的问题, * 如果使用了事件回调,回调里不要直接使用item,会出现不更新的问题,
* 使用getItem(holder.layoutPosition)来获取item * 使用getItem(holder.layoutPosition)来获取item
*/ */
abstract fun convert(holder: ItemViewHolder, item: ITEM, payloads: MutableList<Any>) abstract fun convert(
holder: ItemViewHolder,
binding: VB,
item: ITEM,
payloads: MutableList<Any>
)
/** /**
* 注册事件 * 注册事件
*/ */
abstract fun registerListener(holder: ItemViewHolder) abstract fun registerListener(holder: ItemViewHolder, binding: VB)
} }

@ -55,21 +55,22 @@ class ReadRecordActivity : BaseActivity<ActivityReadRecordBinding>() {
} }
inner class RecordAdapter(context: Context) : inner class RecordAdapter(context: Context) :
SimpleRecyclerAdapter<ReadRecordShow>(context, R.layout.item_read_record) { SimpleRecyclerAdapter<ReadRecordShow, ItemReadRecordBinding>(context) {
override fun convert( override fun convert(
holder: ItemViewHolder, holder: ItemViewHolder,
binding: ItemReadRecordBinding,
item: ReadRecordShow, item: ReadRecordShow,
payloads: MutableList<Any> payloads: MutableList<Any>
) { ) {
ItemReadRecordBinding.bind(holder.itemView).apply { binding.apply {
tvBookName.text = item.bookName tvBookName.text = item.bookName
tvReadTime.text = formatDuring(item.readTime) tvReadTime.text = formatDuring(item.readTime)
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemReadRecordBinding) {
ItemReadRecordBinding.bind(holder.itemView).apply { binding.apply {
ivRemove.onClick { ivRemove.onClick {
alert(R.string.delete, R.string.sure_del) { alert(R.string.delete, R.string.sure_del) {
okButton { okButton {

@ -16,15 +16,15 @@ import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemSourceImportBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.ui.widget.text.AutoCompleteTextView import io.legado.app.ui.widget.text.AutoCompleteTextView
import io.legado.app.utils.getViewModelOfActivity import io.legado.app.utils.getViewModelOfActivity
import io.legado.app.utils.putPrefBoolean import io.legado.app.utils.putPrefBoolean
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.dialog_edit_text.view.*
import kotlinx.android.synthetic.main.dialog_recycler_view.*
import kotlinx.android.synthetic.main.item_source_import.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
/** /**
@ -32,6 +32,8 @@ import org.jetbrains.anko.sdk27.listeners.onClick
*/ */
class ImportBookSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener { class ImportBookSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
private val binding by viewBinding(DialogRecyclerViewBinding::bind)
val viewModel: ImportBookSourceViewModel val viewModel: ImportBookSourceViewModel
get() = getViewModelOfActivity(ImportBookSourceViewModel::class.java) get() = getViewModelOfActivity(ImportBookSourceViewModel::class.java)
lateinit var adapter: SourcesAdapter lateinit var adapter: SourcesAdapter
@ -53,18 +55,18 @@ class ImportBookSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickList
} }
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setTitle(R.string.import_book_source) binding.toolBar.setTitle(R.string.import_book_source)
initMenu() initMenu()
adapter = SourcesAdapter(requireContext()) adapter = SourcesAdapter(requireContext())
recycler_view.layoutManager = LinearLayoutManager(requireContext()) binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
adapter.setItems(viewModel.allSources) adapter.setItems(viewModel.allSources)
tv_cancel.visible() binding.tvCancel.visible()
tv_cancel.onClick { binding.tvCancel.onClick {
dismiss() dismiss()
} }
tv_ok.visible() binding.tvOk.visible()
tv_ok.onClick { binding.tvOk.onClick {
viewModel.importSelect { viewModel.importSelect {
dismiss() dismiss()
} }
@ -72,9 +74,10 @@ class ImportBookSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickList
} }
private fun initMenu() { private fun initMenu() {
tool_bar.setOnMenuItemClickListener(this) binding.toolBar.setOnMenuItemClickListener(this)
tool_bar.inflateMenu(R.menu.import_source) binding.toolBar.inflateMenu(R.menu.import_source)
tool_bar.menu.findItem(R.id.menu_Keep_original_name)?.isChecked = AppConfig.importKeepName binding.toolBar.menu.findItem(R.id.menu_Keep_original_name)
?.isChecked = AppConfig.importKeepName
} }
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
@ -85,7 +88,7 @@ class ImportBookSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickList
var editText: AutoCompleteTextView? = null var editText: AutoCompleteTextView? = null
customView { customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view editText = findViewById(R.id.edit_view)
} }
} }
okButton { okButton {
@ -127,23 +130,30 @@ class ImportBookSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickList
} }
inner class SourcesAdapter(context: Context) : inner class SourcesAdapter(context: Context) :
SimpleRecyclerAdapter<BookSource>(context, R.layout.item_source_import) { SimpleRecyclerAdapter<BookSource, ItemSourceImportBinding>(context) {
override fun convert(holder: ItemViewHolder, item: BookSource, payloads: MutableList<Any>) { override fun convert(
holder.itemView.apply { holder: ItemViewHolder,
cb_source_name.isChecked = viewModel.selectStatus[holder.layoutPosition] binding: ItemSourceImportBinding,
cb_source_name.text = item.bookSourceName item: BookSource,
tv_source_state.text = if (viewModel.checkSources[holder.layoutPosition] != null) { payloads: MutableList<Any>
"已存在" ) {
} else { binding.apply {
"新书源" cbSourceName.isChecked = viewModel.selectStatus[holder.layoutPosition]
} cbSourceName.text = item.bookSourceName
tvSourceState.text =
if (viewModel.checkSources[holder.layoutPosition] != null) {
"已存在"
} else {
"新书源"
}
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemSourceImportBinding) {
holder.itemView.apply { binding.apply {
cb_source_name.setOnCheckedChangeListener { buttonView, isChecked -> cbSourceName.setOnCheckedChangeListener { buttonView, isChecked ->
if (buttonView.isPressed) { if (buttonView.isPressed) {
viewModel.selectStatus[holder.layoutPosition] = isChecked viewModel.selectStatus[holder.layoutPosition] = isChecked
} }

@ -19,10 +19,6 @@ class ImportReplaceRuleActivity :
override val viewModel: ImportReplaceRuleViewModel override val viewModel: ImportReplaceRuleViewModel
get() = getViewModel(ImportReplaceRuleViewModel::class.java) get() = getViewModel(ImportReplaceRuleViewModel::class.java)
override fun getViewBinding(): ActivityTranslucenceBinding {
return ActivityTranslucenceBinding.inflate(layoutInflater)
}
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
binding.rotateLoading.show() binding.rotateLoading.show()
viewModel.errorLiveData.observe(this, { viewModel.errorLiveData.observe(this, {

@ -16,15 +16,15 @@ import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssSource
import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemSourceImportBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.ui.widget.text.AutoCompleteTextView import io.legado.app.ui.widget.text.AutoCompleteTextView
import io.legado.app.utils.getViewModelOfActivity import io.legado.app.utils.getViewModelOfActivity
import io.legado.app.utils.putPrefBoolean import io.legado.app.utils.putPrefBoolean
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.dialog_edit_text.view.*
import kotlinx.android.synthetic.main.dialog_recycler_view.*
import kotlinx.android.synthetic.main.item_source_import.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
/** /**
@ -32,6 +32,8 @@ import org.jetbrains.anko.sdk27.listeners.onClick
*/ */
class ImportRssSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener { class ImportRssSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
private val binding by viewBinding(DialogRecyclerViewBinding::bind)
val viewModel: ImportRssSourceViewModel val viewModel: ImportRssSourceViewModel
get() = getViewModelOfActivity(ImportRssSourceViewModel::class.java) get() = getViewModelOfActivity(ImportRssSourceViewModel::class.java)
lateinit var adapter: SourcesAdapter lateinit var adapter: SourcesAdapter
@ -53,18 +55,18 @@ class ImportRssSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListe
} }
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setTitle(R.string.import_rss_source) binding.toolBar.setTitle(R.string.import_rss_source)
initMenu() initMenu()
adapter = SourcesAdapter(requireContext()) adapter = SourcesAdapter(requireContext())
recycler_view.layoutManager = LinearLayoutManager(requireContext()) binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
adapter.setItems(viewModel.allSources) adapter.setItems(viewModel.allSources)
tv_cancel.visible() binding.tvCancel.visible()
tv_cancel.onClick { binding.tvCancel.onClick {
dismiss() dismiss()
} }
tv_ok.visible() binding.tvOk.visible()
tv_ok.onClick { binding.tvOk.onClick {
viewModel.importSelect { viewModel.importSelect {
dismiss() dismiss()
} }
@ -72,9 +74,10 @@ class ImportRssSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListe
} }
private fun initMenu() { private fun initMenu() {
tool_bar.setOnMenuItemClickListener(this) binding.toolBar.setOnMenuItemClickListener(this)
tool_bar.inflateMenu(R.menu.import_source) binding.toolBar.inflateMenu(R.menu.import_source)
tool_bar.menu.findItem(R.id.menu_Keep_original_name)?.isChecked = AppConfig.importKeepName binding.toolBar.menu.findItem(R.id.menu_Keep_original_name)?.isChecked =
AppConfig.importKeepName
} }
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
@ -85,7 +88,7 @@ class ImportRssSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListe
var editText: AutoCompleteTextView? = null var editText: AutoCompleteTextView? = null
customView { customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view editText = findViewById(R.id.edit_view)
} }
} }
okButton { okButton {
@ -127,13 +130,18 @@ class ImportRssSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListe
} }
inner class SourcesAdapter(context: Context) : inner class SourcesAdapter(context: Context) :
SimpleRecyclerAdapter<RssSource>(context, R.layout.item_source_import) { SimpleRecyclerAdapter<RssSource, ItemSourceImportBinding>(context) {
override fun convert(holder: ItemViewHolder, item: RssSource, payloads: MutableList<Any>) { override fun convert(
holder.itemView.apply { holder: ItemViewHolder,
cb_source_name.isChecked = viewModel.selectStatus[holder.layoutPosition] binding: ItemSourceImportBinding,
cb_source_name.text = item.sourceName item: RssSource,
tv_source_state.text = if (viewModel.checkSources[holder.layoutPosition] != null) { payloads: MutableList<Any>
) {
binding.apply {
cbSourceName.isChecked = viewModel.selectStatus[holder.layoutPosition]
cbSourceName.text = item.sourceName
tvSourceState.text = if (viewModel.checkSources[holder.layoutPosition] != null) {
"已存在" "已存在"
} else { } else {
"新订阅源" "新订阅源"
@ -141,9 +149,9 @@ class ImportRssSourceDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListe
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemSourceImportBinding) {
holder.itemView.apply { binding.apply {
cb_source_name.setOnCheckedChangeListener { buttonView, isChecked -> cbSourceName.setOnCheckedChangeListener { buttonView, isChecked ->
if (buttonView.isPressed) { if (buttonView.isPressed) {
viewModel.selectStatus[holder.layoutPosition] = isChecked viewModel.selectStatus[holder.layoutPosition] = isChecked
} }

@ -4,21 +4,20 @@ import android.content.Context
import android.view.View import android.view.View
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.ItemArrangeBookBinding
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
import kotlinx.android.synthetic.main.item_arrange_book.view.*
import org.jetbrains.anko.backgroundColor import org.jetbrains.anko.backgroundColor
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.* import java.util.*
class ArrangeBookAdapter(context: Context, val callBack: CallBack) : class ArrangeBookAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<Book>(context, R.layout.item_arrange_book), SimpleRecyclerAdapter<Book, ItemArrangeBookBinding>(context),
ItemTouchCallback.Callback { ItemTouchCallback.Callback {
val groupRequestCode = 12 val groupRequestCode = 12
private val selectedBooks: HashSet<Book> = hashSetOf() private val selectedBooks: HashSet<Book> = hashSetOf()
@ -58,19 +57,24 @@ class ArrangeBookAdapter(context: Context, val callBack: CallBack) :
return books.toTypedArray() return books.toTypedArray()
} }
override fun convert(holder: ItemViewHolder, item: Book, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
backgroundColor = context.backgroundColor binding: ItemArrangeBookBinding,
tv_name.text = item.name item: Book,
tv_author.text = item.author payloads: MutableList<Any>
tv_author.visibility = if (item.author.isEmpty()) View.GONE else View.VISIBLE ) {
tv_group_s.text = getGroupName(item.group) binding.apply {
root.backgroundColor = context.backgroundColor
tvName.text = item.name
tvAuthor.text = item.author
tvAuthor.visibility = if (item.author.isEmpty()) View.GONE else View.VISIBLE
tvGroupS.text = getGroupName(item.group)
checkbox.isChecked = selectedBooks.contains(item) checkbox.isChecked = selectedBooks.contains(item)
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemArrangeBookBinding) {
holder.itemView.apply { binding.apply {
checkbox.setOnCheckedChangeListener { buttonView, isChecked -> checkbox.setOnCheckedChangeListener { buttonView, isChecked ->
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
if (buttonView.isPressed) { if (buttonView.isPressed) {
@ -84,7 +88,7 @@ class ArrangeBookAdapter(context: Context, val callBack: CallBack) :
} }
} }
onClick { root.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
checkbox.isChecked = !checkbox.isChecked checkbox.isChecked = !checkbox.isChecked
if (checkbox.isChecked) { if (checkbox.isChecked) {
@ -95,12 +99,12 @@ class ArrangeBookAdapter(context: Context, val callBack: CallBack) :
callBack.upSelectCount() callBack.upSelectCount()
} }
} }
tv_delete.onClick { tvDelete.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callBack.deleteBook(it) callBack.deleteBook(it)
} }
} }
tv_group.onClick { tvGroup.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
actionItem = it actionItem = it
callBack.selectGroup(groupRequestCode, it.group) callBack.selectGroup(groupRequestCode, it.group)

@ -7,44 +7,49 @@ import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.databinding.ItemDownloadBinding
import io.legado.app.service.help.CacheBook import io.legado.app.service.help.CacheBook
import kotlinx.android.synthetic.main.item_download.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArraySet import java.util.concurrent.CopyOnWriteArraySet
class CacheAdapter(context: Context, private val callBack: CallBack) : class CacheAdapter(context: Context, private val callBack: CallBack) :
SimpleRecyclerAdapter<Book>(context, R.layout.item_download) { SimpleRecyclerAdapter<Book, ItemDownloadBinding>(context) {
val cacheChapters = hashMapOf<String, HashSet<String>>() val cacheChapters = hashMapOf<String, HashSet<String>>()
var downloadMap: ConcurrentHashMap<String, CopyOnWriteArraySet<BookChapter>>? = null var downloadMap: ConcurrentHashMap<String, CopyOnWriteArraySet<BookChapter>>? = null
override fun convert(holder: ItemViewHolder, item: Book, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
binding: ItemDownloadBinding,
item: Book,
payloads: MutableList<Any>
) {
with(binding) {
if (payloads.isEmpty()) { if (payloads.isEmpty()) {
tv_name.text = item.name tvName.text = item.name
tv_author.text = context.getString(R.string.author_show, item.getRealAuthor()) tvAuthor.text = context.getString(R.string.author_show, item.getRealAuthor())
val cs = cacheChapters[item.bookUrl] val cs = cacheChapters[item.bookUrl]
if (cs == null) { if (cs == null) {
tv_download.setText(R.string.loading) tvDownload.setText(R.string.loading)
} else { } else {
tv_download.text = tvDownload.text =
context.getString(R.string.download_count, cs.size, item.totalChapterNum) context.getString(R.string.download_count, cs.size, item.totalChapterNum)
} }
upDownloadIv(iv_download, item) upDownloadIv(ivDownload, item)
} else { } else {
val cacheSize = cacheChapters[item.bookUrl]?.size ?: 0 val cacheSize = cacheChapters[item.bookUrl]?.size ?: 0
tv_download.text = tvDownload.text =
context.getString(R.string.download_count, cacheSize, item.totalChapterNum) context.getString(R.string.download_count, cacheSize, item.totalChapterNum)
upDownloadIv(iv_download, item) upDownloadIv(ivDownload, item)
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemDownloadBinding) {
holder.itemView.apply { with(binding) {
iv_download.onClick { ivDownload.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
if (downloadMap?.containsKey(it.bookUrl) == true) { if (downloadMap?.containsKey(it.bookUrl) == true) {
CacheBook.remove(context, it.bookUrl) CacheBook.remove(context, it.bookUrl)
@ -53,7 +58,7 @@ class CacheAdapter(context: Context, private val callBack: CallBack) :
} }
} }
} }
tv_export.onClick { tvExport.onClick {
callBack.export(holder.layoutPosition) callBack.export(holder.layoutPosition)
} }
} }

@ -12,11 +12,12 @@ import androidx.recyclerview.widget.GridLayoutManager
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.Theme import io.legado.app.constant.Theme
import io.legado.app.databinding.DialogChangeCoverBinding
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.utils.applyTint import io.legado.app.utils.applyTint
import io.legado.app.utils.getSize import io.legado.app.utils.getSize
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
import kotlinx.android.synthetic.main.dialog_change_source.* import io.legado.app.utils.viewbindingdelegate.viewBinding
class ChangeCoverDialog : BaseDialogFragment(), class ChangeCoverDialog : BaseDialogFragment(),
@ -38,6 +39,7 @@ class ChangeCoverDialog : BaseDialogFragment(),
} }
} }
private val binding by viewBinding(DialogChangeCoverBinding::bind)
private var callBack: CallBack? = null private var callBack: CallBack? = null
private lateinit var viewModel: ChangeCoverViewModel private lateinit var viewModel: ChangeCoverViewModel
lateinit var adapter: CoverAdapter lateinit var adapter: CoverAdapter
@ -59,36 +61,36 @@ class ChangeCoverDialog : BaseDialogFragment(),
} }
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
tool_bar.setTitle(R.string.change_cover_source) binding.toolBar.setTitle(R.string.change_cover_source)
viewModel.initData(arguments) viewModel.initData(arguments)
initMenu() initMenu()
initView() initView()
} }
private fun initMenu() { private fun initMenu() {
tool_bar.inflateMenu(R.menu.change_cover) binding.toolBar.inflateMenu(R.menu.change_cover)
tool_bar.menu.applyTint(requireContext()) binding.toolBar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this) binding.toolBar.setOnMenuItemClickListener(this)
} }
private fun initView() { private fun initView() {
recycler_view.layoutManager = GridLayoutManager(requireContext(), 3) binding.recyclerView.layoutManager = GridLayoutManager(requireContext(), 3)
adapter = CoverAdapter(requireContext(), this) adapter = CoverAdapter(requireContext(), this)
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
viewModel.loadDbSearchBook() viewModel.loadDbSearchBook()
} }
override fun observeLiveBus() { override fun observeLiveBus() {
super.observeLiveBus() super.observeLiveBus()
viewModel.searchStateData.observe(viewLifecycleOwner, { viewModel.searchStateData.observe(viewLifecycleOwner, {
refresh_progress_bar.isAutoLoading = it binding.refreshProgressBar.isAutoLoading = it
if (it) { if (it) {
stopMenuItem?.setIcon(R.drawable.ic_stop_black_24dp) stopMenuItem?.setIcon(R.drawable.ic_stop_black_24dp)
} else { } else {
stopMenuItem?.setIcon(R.drawable.ic_refresh_black_24dp) stopMenuItem?.setIcon(R.drawable.ic_refresh_black_24dp)
} }
tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) binding.toolBar.menu.applyTint(requireContext(), Theme.getTheme())
}) })
viewModel.searchBooksLiveData.observe(viewLifecycleOwner, { viewModel.searchBooksLiveData.observe(viewLifecycleOwner, {
val diffResult = DiffUtil.calculateDiff(DiffCallBack(adapter.getItems(), it)) val diffResult = DiffUtil.calculateDiff(DiffCallBack(adapter.getItems(), it))
@ -105,7 +107,7 @@ class ChangeCoverDialog : BaseDialogFragment(),
} }
private val stopMenuItem: MenuItem? private val stopMenuItem: MenuItem?
get() = tool_bar.menu.findItem(R.id.menu_stop) get() = binding.toolBar.menu.findItem(R.id.menu_stop)
override fun changeTo(coverUrl: String) { override fun changeTo(coverUrl: String) {
callBack?.coverChangeTo(coverUrl) callBack?.coverChangeTo(coverUrl)

@ -1,7 +1,6 @@
package io.legado.app.ui.book.changecover package io.legado.app.ui.book.changecover
import android.content.Context import android.content.Context
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.SearchBook
@ -9,16 +8,21 @@ import io.legado.app.databinding.ItemCoverBinding
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class CoverAdapter(context: Context, val callBack: CallBack) : class CoverAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<SearchBook>(context, R.layout.item_cover) { SimpleRecyclerAdapter<SearchBook, ItemCoverBinding>(context) {
override fun convert(holder: ItemViewHolder, item: SearchBook, payloads: MutableList<Any>) { override fun convert(
ItemCoverBinding.bind(holder.itemView).apply { holder: ItemViewHolder,
binding: ItemCoverBinding,
item: SearchBook,
payloads: MutableList<Any>
) {
binding.apply {
ivCover.load(item.coverUrl, item.name, item.author) ivCover.load(item.coverUrl, item.name, item.author)
tvSource.text = item.originName tvSource.text = item.originName
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemCoverBinding) {
holder.itemView.apply { holder.itemView.apply {
onClick { onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {

@ -8,39 +8,44 @@ import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.ItemChangeSourceBinding
import io.legado.app.utils.invisible import io.legado.app.utils.invisible
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_change_source.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onLongClick import org.jetbrains.anko.sdk27.listeners.onLongClick
class ChangeSourceAdapter(context: Context, val callBack: CallBack) : class ChangeSourceAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<SearchBook>(context, R.layout.item_change_source) { SimpleRecyclerAdapter<SearchBook, ItemChangeSourceBinding>(context) {
override fun convert(holder: ItemViewHolder, item: SearchBook, payloads: MutableList<Any>) { override fun convert(
holder: ItemViewHolder,
binding: ItemChangeSourceBinding,
item: SearchBook,
payloads: MutableList<Any>
) {
val bundle = payloads.getOrNull(0) as? Bundle val bundle = payloads.getOrNull(0) as? Bundle
holder.itemView.apply { binding.apply {
if (bundle == null) { if (bundle == null) {
tv_origin.text = item.originName tvOrigin.text = item.originName
tv_last.text = item.getDisplayLastChapterTitle() tvLast.text = item.getDisplayLastChapterTitle()
if (callBack.bookUrl == item.bookUrl) { if (callBack.bookUrl == item.bookUrl) {
iv_checked.visible() ivChecked.visible()
} else { } else {
iv_checked.invisible() ivChecked.invisible()
} }
} else { } else {
bundle.keySet().map { bundle.keySet().map {
when (it) { when (it) {
"name" -> tv_origin.text = item.originName "name" -> tvOrigin.text = item.originName
"latest" -> tv_last.text = item.getDisplayLastChapterTitle() "latest" -> tvLast.text = item.getDisplayLastChapterTitle()
} }
} }
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemChangeSourceBinding) {
holder.itemView.onClick { holder.itemView.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callBack.changeTo(it) callBack.changeTo(it)

@ -16,6 +16,7 @@ import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.DialogChangeSourceBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
@ -23,7 +24,7 @@ import io.legado.app.utils.applyTint
import io.legado.app.utils.getSize import io.legado.app.utils.getSize
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
import io.legado.app.utils.putPrefBoolean import io.legado.app.utils.putPrefBoolean
import kotlinx.android.synthetic.main.dialog_change_source.* import io.legado.app.utils.viewbindingdelegate.viewBinding
class ChangeSourceDialog : BaseDialogFragment(), class ChangeSourceDialog : BaseDialogFragment(),
@ -45,6 +46,7 @@ class ChangeSourceDialog : BaseDialogFragment(),
} }
} }
private val binding by viewBinding(DialogChangeSourceBinding::bind)
private var callBack: CallBack? = null private var callBack: CallBack? = null
private lateinit var viewModel: ChangeSourceViewModel private lateinit var viewModel: ChangeSourceViewModel
lateinit var adapter: ChangeSourceAdapter lateinit var adapter: ChangeSourceAdapter
@ -66,7 +68,7 @@ class ChangeSourceDialog : BaseDialogFragment(),
} }
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
viewModel.initData(arguments) viewModel.initData(arguments)
showTitle() showTitle()
initMenu() initMenu()
@ -77,47 +79,48 @@ class ChangeSourceDialog : BaseDialogFragment(),
} }
private fun showTitle() { private fun showTitle() {
tool_bar.title = viewModel.name binding.toolBar.title = viewModel.name
tool_bar.subtitle = getString(R.string.author_show, viewModel.author) binding.toolBar.subtitle = getString(R.string.author_show, viewModel.author)
} }
private fun initMenu() { private fun initMenu() {
tool_bar.inflateMenu(R.menu.change_source) binding.toolBar.inflateMenu(R.menu.change_source)
tool_bar.menu.applyTint(requireContext()) binding.toolBar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this) binding.toolBar.setOnMenuItemClickListener(this)
tool_bar.menu.findItem(R.id.menu_load_info)?.isChecked = AppConfig.changeSourceLoadInfo binding.toolBar.menu.findItem(R.id.menu_load_info)?.isChecked =
tool_bar.menu.findItem(R.id.menu_load_toc)?.isChecked = AppConfig.changeSourceLoadToc AppConfig.changeSourceLoadInfo
binding.toolBar.menu.findItem(R.id.menu_load_toc)?.isChecked = AppConfig.changeSourceLoadToc
} }
private fun initRecyclerView() { private fun initRecyclerView() {
adapter = ChangeSourceAdapter(requireContext(), this) adapter = ChangeSourceAdapter(requireContext(), this)
recycler_view.layoutManager = LinearLayoutManager(context) binding.recyclerView.layoutManager = LinearLayoutManager(context)
recycler_view.addItemDecoration(VerticalDivider(requireContext())) binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
if (positionStart == 0) { if (positionStart == 0) {
recycler_view.scrollToPosition(0) binding.recyclerView.scrollToPosition(0)
} }
} }
override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) { override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
if (toPosition == 0) { if (toPosition == 0) {
recycler_view.scrollToPosition(0) binding.recyclerView.scrollToPosition(0)
} }
} }
}) })
} }
private fun initSearchView() { private fun initSearchView() {
val searchView = tool_bar.menu.findItem(R.id.menu_screen).actionView as SearchView val searchView = binding.toolBar.menu.findItem(R.id.menu_screen).actionView as SearchView
searchView.setOnCloseListener { searchView.setOnCloseListener {
showTitle() showTitle()
false false
} }
searchView.setOnSearchClickListener { searchView.setOnSearchClickListener {
tool_bar.title = "" binding.toolBar.title = ""
tool_bar.subtitle = "" binding.toolBar.subtitle = ""
} }
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean { override fun onQueryTextSubmit(query: String?): Boolean {
@ -134,13 +137,13 @@ class ChangeSourceDialog : BaseDialogFragment(),
private fun initLiveData() { private fun initLiveData() {
viewModel.searchStateData.observe(viewLifecycleOwner, { viewModel.searchStateData.observe(viewLifecycleOwner, {
refresh_progress_bar.isAutoLoading = it binding.refreshProgressBar.isAutoLoading = it
if (it) { if (it) {
stopMenuItem?.setIcon(R.drawable.ic_stop_black_24dp) stopMenuItem?.setIcon(R.drawable.ic_stop_black_24dp)
} else { } else {
stopMenuItem?.setIcon(R.drawable.ic_refresh_black_24dp) stopMenuItem?.setIcon(R.drawable.ic_refresh_black_24dp)
} }
tool_bar.menu.applyTint(requireContext()) binding.toolBar.menu.applyTint(requireContext())
}) })
viewModel.searchBooksLiveData.observe(viewLifecycleOwner, { viewModel.searchBooksLiveData.observe(viewLifecycleOwner, {
val diffResult = DiffUtil.calculateDiff(DiffCallBack(adapter.getItems(), it)) val diffResult = DiffUtil.calculateDiff(DiffCallBack(adapter.getItems(), it))
@ -150,7 +153,7 @@ class ChangeSourceDialog : BaseDialogFragment(),
} }
private val stopMenuItem: MenuItem? private val stopMenuItem: MenuItem?
get() = tool_bar.menu.findItem(R.id.menu_stop) get() = binding.toolBar.menu.findItem(R.id.menu_stop)
override fun onMenuItemClick(item: MenuItem?): Boolean { override fun onMenuItemClick(item: MenuItem?): Boolean {
when (item?.itemId) { when (item?.itemId) {

@ -8,6 +8,7 @@ import io.legado.app.base.VMBaseActivity
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.ActivityExploreShowBinding import io.legado.app.databinding.ActivityExploreShowBinding
import io.legado.app.databinding.ViewLoadMoreBinding
import io.legado.app.ui.book.info.BookInfoActivity import io.legado.app.ui.book.info.BookInfoActivity
import io.legado.app.ui.widget.recycler.LoadMoreView import io.legado.app.ui.widget.recycler.LoadMoreView
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
@ -36,7 +37,7 @@ class ExploreShowActivity : VMBaseActivity<ActivityExploreShowBinding, ExploreSh
binding.recyclerView.addItemDecoration(VerticalDivider(this)) binding.recyclerView.addItemDecoration(VerticalDivider(this))
binding.recyclerView.adapter = adapter binding.recyclerView.adapter = adapter
loadMoreView = LoadMoreView(this) loadMoreView = LoadMoreView(this)
adapter.addFooterView(loadMoreView) adapter.addFooterView(ViewLoadMoreBinding.bind(loadMoreView))
loadMoreView.startLoad() loadMoreView.startLoad()
loadMoreView.setOnClickListener { loadMoreView.setOnClickListener {
if (!isLoading) { if (!isLoading) {

@ -6,43 +6,46 @@ import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.ItemSearchBinding
import io.legado.app.utils.gone import io.legado.app.utils.gone
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_bookshelf_list.view.iv_cover
import kotlinx.android.synthetic.main.item_bookshelf_list.view.tv_name
import kotlinx.android.synthetic.main.item_search.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class ExploreShowAdapter(context: Context, val callBack: CallBack) : class ExploreShowAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<SearchBook>(context, R.layout.item_search) { SimpleRecyclerAdapter<SearchBook, ItemSearchBinding>(context) {
override fun convert(holder: ItemViewHolder, item: SearchBook, payloads: MutableList<Any>) { override fun convert(
holder.itemView.apply { holder: ItemViewHolder,
tv_name.text = item.name binding: ItemSearchBinding,
tv_author.text = context.getString(R.string.author_show, item.author) item: SearchBook,
payloads: MutableList<Any>
) {
binding.apply {
tvName.text = item.name
tvAuthor.text = context.getString(R.string.author_show, item.author)
if (item.latestChapterTitle.isNullOrEmpty()) { if (item.latestChapterTitle.isNullOrEmpty()) {
tv_lasted.gone() tvLasted.gone()
} else { } else {
tv_lasted.text = context.getString(R.string.lasted_show, item.latestChapterTitle) tvLasted.text = context.getString(R.string.lasted_show, item.latestChapterTitle)
tv_lasted.visible() tvLasted.visible()
} }
if (item.intro.isNullOrEmpty()) { if (item.intro.isNullOrEmpty()) {
tv_introduce.text = context.getString(R.string.intro_show_null) tvIntroduce.text = context.getString(R.string.intro_show_null)
} else { } else {
tv_introduce.text = context.getString(R.string.intro_show, item.intro) tvIntroduce.text = context.getString(R.string.intro_show, item.intro)
} }
val kinds = item.getKindList() val kinds = item.getKindList()
if (kinds.isEmpty()) { if (kinds.isEmpty()) {
ll_kind.gone() llKind.gone()
} else { } else {
ll_kind.visible() llKind.visible()
ll_kind.setLabels(kinds) llKind.setLabels(kinds)
} }
iv_cover.load(item.coverUrl, item.name, item.author) ivCover.load(item.coverUrl, item.name, item.author)
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemSearchBinding) {
holder.itemView.onClick { holder.itemView.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callBack.showBookInfo(it.toBook()) callBack.showBookInfo(it.toBook())

@ -20,16 +20,16 @@ import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookGroup
import io.legado.app.lib.dialogs.* import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemGroupManageBinding
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.dialog_recycler_view.*
import kotlinx.android.synthetic.main.item_group_manage.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
@ -37,6 +37,7 @@ import kotlin.collections.ArrayList
class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener { class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
private lateinit var viewModel: GroupViewModel private lateinit var viewModel: GroupViewModel
private lateinit var adapter: GroupAdapter private lateinit var adapter: GroupAdapter
private val binding by viewBinding(DialogRecyclerViewBinding::bind)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
@ -54,8 +55,8 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
} }
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
tool_bar.title = getString(R.string.group_manage) binding.toolBar.title = getString(R.string.group_manage)
initView() initView()
initData() initData()
initMenu() initMenu()
@ -63,15 +64,15 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun initView() { private fun initView() {
adapter = GroupAdapter(requireContext()) adapter = GroupAdapter(requireContext())
recycler_view.layoutManager = LinearLayoutManager(requireContext()) binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(VerticalDivider(requireContext())) binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
val itemTouchCallback = ItemTouchCallback(adapter) val itemTouchCallback = ItemTouchCallback(adapter)
itemTouchCallback.isCanDrag = true itemTouchCallback.isCanDrag = true
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(recycler_view) ItemTouchHelper(itemTouchCallback).attachToRecyclerView(binding.recyclerView)
tv_ok.setTextColor(requireContext().accentColor) binding.tvOk.setTextColor(requireContext().accentColor)
tv_ok.visible() binding.tvOk.visible()
tv_ok.onClick { dismiss() } binding.tvOk.onClick { dismiss() }
} }
private fun initData() { private fun initData() {
@ -83,9 +84,9 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
} }
private fun initMenu() { private fun initMenu() {
tool_bar.setOnMenuItemClickListener(this) binding.toolBar.setOnMenuItemClickListener(this)
tool_bar.inflateMenu(R.menu.book_group_manage) binding.toolBar.inflateMenu(R.menu.book_group_manage)
tool_bar.menu.applyTint(requireContext()) binding.toolBar.menu.applyTint(requireContext())
} }
override fun onMenuItemClick(item: MenuItem?): Boolean { override fun onMenuItemClick(item: MenuItem?): Boolean {
@ -101,9 +102,8 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
var editText: EditText? = null var editText: EditText? = null
customView { customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view.apply { editText = findViewById(R.id.edit_view)
setHint(R.string.group_name) editText?.setHint(R.string.group_name)
}
} }
} }
yesButton { yesButton {
@ -123,10 +123,9 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
var editText: EditText? = null var editText: EditText? = null
customView { customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view.apply { editText = findViewById(R.id.edit_view)
setHint(R.string.group_name) editText!!.setHint(R.string.group_name)
setText(bookGroup.groupName) editText!!.setText(bookGroup.groupName)
}
} }
} }
yesButton { yesButton {
@ -174,26 +173,31 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
} }
private inner class GroupAdapter(context: Context) : private inner class GroupAdapter(context: Context) :
SimpleRecyclerAdapter<BookGroup>(context, R.layout.item_group_manage), SimpleRecyclerAdapter<BookGroup, ItemGroupManageBinding>(context),
ItemTouchCallback.Callback { ItemTouchCallback.Callback {
private var isMoved = false private var isMoved = false
override fun convert(holder: ItemViewHolder, item: BookGroup, payloads: MutableList<Any>) { override fun convert(
holder.itemView.apply { holder: ItemViewHolder,
setBackgroundColor(context.backgroundColor) binding: ItemGroupManageBinding,
tv_group.text = item.getManageName(context) item: BookGroup,
sw_show.isChecked = item.show payloads: MutableList<Any>
tv_del.isGone = item.groupId < 0 ) {
sw_show.isGone = item.groupId >= 0 with(binding) {
root.setBackgroundColor(context.backgroundColor)
tvGroup.text = item.getManageName(context)
swShow.isChecked = item.show
tvDel.isGone = item.groupId < 0
swShow.isGone = item.groupId >= 0
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemGroupManageBinding) {
holder.itemView.apply { with(binding) {
tv_edit.onClick { getItem(holder.layoutPosition)?.let { editGroup(it) } } tvEdit.onClick { getItem(holder.layoutPosition)?.let { editGroup(it) } }
tv_del.onClick { getItem(holder.layoutPosition)?.let { deleteGroup(it) } } tvDel.onClick { getItem(holder.layoutPosition)?.let { deleteGroup(it) } }
sw_show.setOnCheckedChangeListener { buttonView, isChecked -> swShow.setOnCheckedChangeListener { buttonView, isChecked ->
if (buttonView.isPressed) { if (buttonView.isPressed) {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
viewModel.upGroup(it.copy(show = isChecked)) viewModel.upGroup(it.copy(show = isChecked))

@ -19,6 +19,8 @@ import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.DialogBookGroupPickerBinding
import io.legado.app.databinding.ItemGroupSelectBinding
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
@ -29,10 +31,7 @@ import io.legado.app.utils.applyTint
import io.legado.app.utils.getSize import io.legado.app.utils.getSize
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
import io.legado.app.utils.requestInputMethod import io.legado.app.utils.requestInputMethod
import kotlinx.android.synthetic.main.dialog_book_group_picker.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.dialog_edit_text.view.*
import kotlinx.android.synthetic.main.dialog_recycler_view.tool_bar
import kotlinx.android.synthetic.main.item_group_select.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.* import java.util.*
@ -52,6 +51,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
} }
} }
private val binding by viewBinding(DialogBookGroupPickerBinding::bind)
private var requestCode: Int = -1 private var requestCode: Int = -1
private lateinit var viewModel: GroupViewModel private lateinit var viewModel: GroupViewModel
private lateinit var adapter: GroupAdapter private lateinit var adapter: GroupAdapter
@ -74,7 +74,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
} }
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
callBack = activity as? CallBack callBack = activity as? CallBack
arguments?.let { arguments?.let {
groupId = it.getLong("groupId") groupId = it.getLong("groupId")
@ -85,20 +85,20 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
} }
private fun initView() { private fun initView() {
tool_bar.title = getString(R.string.group_select) binding.toolBar.title = getString(R.string.group_select)
tool_bar.inflateMenu(R.menu.book_group_manage) binding.toolBar.inflateMenu(R.menu.book_group_manage)
tool_bar.menu.applyTint(requireContext()) binding.toolBar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this) binding.toolBar.setOnMenuItemClickListener(this)
adapter = GroupAdapter(requireContext()) adapter = GroupAdapter(requireContext())
recycler_view.layoutManager = LinearLayoutManager(requireContext()) binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(VerticalDivider(requireContext())) binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
val itemTouchCallback = ItemTouchCallback(adapter) val itemTouchCallback = ItemTouchCallback(adapter)
itemTouchCallback.isCanDrag = true itemTouchCallback.isCanDrag = true
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(recycler_view) ItemTouchHelper(itemTouchCallback).attachToRecyclerView(binding.recyclerView)
tv_cancel.onClick { dismiss() } binding.tvCancel.onClick { dismiss() }
tv_ok.setTextColor(requireContext().accentColor) binding.tvOk.setTextColor(requireContext().accentColor)
tv_ok.onClick { binding.tvOk.onClick {
callBack?.upGroup(requestCode, groupId) callBack?.upGroup(requestCode, groupId)
dismiss() dismiss()
} }
@ -123,9 +123,8 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
var editText: EditText? = null var editText: EditText? = null
customView { customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view.apply { editText = findViewById(R.id.edit_view)
setHint(R.string.group_name) editText!!.setHint(R.string.group_name)
}
} }
} }
yesButton { yesButton {
@ -145,10 +144,9 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
var editText: EditText? = null var editText: EditText? = null
customView { customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view.apply { editText = findViewById(R.id.edit_view)
setHint(R.string.group_name) editText!!.setHint(R.string.group_name)
setText(bookGroup.groupName) editText!!.setText(bookGroup.groupName)
}
} }
} }
yesButton { yesButton {
@ -159,22 +157,27 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
} }
private inner class GroupAdapter(context: Context) : private inner class GroupAdapter(context: Context) :
SimpleRecyclerAdapter<BookGroup>(context, R.layout.item_group_select), SimpleRecyclerAdapter<BookGroup, ItemGroupSelectBinding>(context),
ItemTouchCallback.Callback { ItemTouchCallback.Callback {
private var isMoved: Boolean = false private var isMoved: Boolean = false
override fun convert(holder: ItemViewHolder, item: BookGroup, payloads: MutableList<Any>) { override fun convert(
holder.itemView.apply { holder: ItemViewHolder,
setBackgroundColor(context.backgroundColor) binding: ItemGroupSelectBinding,
cb_group.text = item.groupName item: BookGroup,
cb_group.isChecked = (groupId and item.groupId) > 0 payloads: MutableList<Any>
) {
with(binding) {
root.setBackgroundColor(context.backgroundColor)
cbGroup.text = item.groupName
cbGroup.isChecked = (groupId and item.groupId) > 0
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemGroupSelectBinding) {
holder.itemView.apply { with(binding) {
cb_group.setOnCheckedChangeListener { buttonView, isChecked -> cbGroup.setOnCheckedChangeListener { buttonView, isChecked ->
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
if (buttonView.isPressed) { if (buttonView.isPressed) {
groupId = if (isChecked) { groupId = if (isChecked) {
@ -185,7 +188,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
} }
} }
} }
tv_edit.onClick { getItem(holder.layoutPosition)?.let { editGroup(it) } } tvEdit.onClick { getItem(holder.layoutPosition)?.let { editGroup(it) } }
} }
} }

@ -5,27 +5,32 @@ import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.databinding.ItemChapterListBinding
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import kotlinx.android.synthetic.main.item_chapter_list.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.textColorResource import org.jetbrains.anko.textColorResource
class ChapterListAdapter(context: Context, var callBack: CallBack) : class ChapterListAdapter(context: Context, var callBack: CallBack) :
SimpleRecyclerAdapter<BookChapter>(context, R.layout.item_chapter_list) { SimpleRecyclerAdapter<BookChapter, ItemChapterListBinding>(context) {
override fun convert(holder: ItemViewHolder, item: BookChapter, payloads: MutableList<Any>) { override fun convert(
holder.itemView.apply { holder: ItemViewHolder,
tv_chapter_name.text = item.title binding: ItemChapterListBinding,
item: BookChapter,
payloads: MutableList<Any>
) {
with(binding) {
tvChapterName.text = item.title
if (item.index == callBack.durChapterIndex()) { if (item.index == callBack.durChapterIndex()) {
tv_chapter_name.setTextColor(context.accentColor) tvChapterName.setTextColor(context.accentColor)
} else { } else {
tv_chapter_name.textColorResource = R.color.secondaryText tvChapterName.textColorResource = R.color.secondaryText
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemChapterListBinding) {
holder.itemView.apply { holder.itemView.apply {
this.onClick { this.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {

@ -6,13 +6,13 @@ import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.databinding.ItemImportBookBinding
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.item_import_book.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class ImportBookAdapter(context: Context, val callBack: CallBack) : class ImportBookAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<DocItem>(context, R.layout.item_import_book) { SimpleRecyclerAdapter<DocItem, ItemImportBookBinding>(context) {
var selectedUris = hashSetOf<String>() var selectedUris = hashSetOf<String>()
var checkableCount = 0 var checkableCount = 0
private var bookFileNames = arrayListOf<String>() private var bookFileNames = arrayListOf<String>()
@ -77,38 +77,43 @@ class ImportBookAdapter(context: Context, val callBack: CallBack) :
} }
} }
override fun convert(holder: ItemViewHolder, item: DocItem, payloads: MutableList<Any>) { override fun convert(
holder.itemView.apply { holder: ItemViewHolder,
binding: ItemImportBookBinding,
item: DocItem,
payloads: MutableList<Any>
) {
with(binding) {
if (payloads.isEmpty()) { if (payloads.isEmpty()) {
if (item.isDir) { if (item.isDir) {
iv_icon.setImageResource(R.drawable.ic_folder) ivIcon.setImageResource(R.drawable.ic_folder)
iv_icon.visible() ivIcon.visible()
cb_select.invisible() cbSelect.invisible()
ll_brief.gone() llBrief.gone()
cb_select.isChecked = false cbSelect.isChecked = false
} else { } else {
if (bookFileNames.contains(item.name)) { if (bookFileNames.contains(item.name)) {
iv_icon.setImageResource(R.drawable.ic_book_has) ivIcon.setImageResource(R.drawable.ic_book_has)
iv_icon.visible() ivIcon.visible()
cb_select.invisible() cbSelect.invisible()
} else { } else {
iv_icon.invisible() ivIcon.invisible()
cb_select.visible() cbSelect.visible()
} }
ll_brief.visible() llBrief.visible()
tv_tag.text = item.name.substringAfterLast(".") tvTag.text = item.name.substringAfterLast(".")
tv_size.text = StringUtils.toSize(item.size) tvSize.text = StringUtils.toSize(item.size)
tv_date.text = AppConst.dateFormat.format(item.date) tvDate.text = AppConst.dateFormat.format(item.date)
cb_select.isChecked = selectedUris.contains(item.uri.toString()) cbSelect.isChecked = selectedUris.contains(item.uri.toString())
} }
tv_name.text = item.name tvName.text = item.name
} else { } else {
cb_select.isChecked = selectedUris.contains(item.uri.toString()) cbSelect.isChecked = selectedUris.contains(item.uri.toString())
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemImportBookBinding) {
holder.itemView.onClick { holder.itemView.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
if (it.isDir) { if (it.isDir) {

@ -20,13 +20,13 @@ import androidx.core.view.isVisible
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.databinding.ItemTextBinding
import io.legado.app.databinding.PopupActionMenuBinding
import io.legado.app.service.BaseReadAloudService import io.legado.app.service.BaseReadAloudService
import io.legado.app.utils.gone import io.legado.app.utils.gone
import io.legado.app.utils.isAbsUrl import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.sendToClip import io.legado.app.utils.sendToClip
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_fillet_text.view.*
import kotlinx.android.synthetic.main.popup_action_menu.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.share import org.jetbrains.anko.share
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
@ -36,14 +36,14 @@ import java.util.*
class TextActionMenu(private val context: Context, private val callBack: CallBack) : class TextActionMenu(private val context: Context, private val callBack: CallBack) :
PopupWindow(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT), PopupWindow(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT),
TextToSpeech.OnInitListener { TextToSpeech.OnInitListener {
private val binding = PopupActionMenuBinding.inflate(LayoutInflater.from(context))
private val adapter = Adapter(context) private val adapter = Adapter(context)
private val menu = MenuBuilder(context) private val menu = MenuBuilder(context)
private val moreMenu = MenuBuilder(context) private val moreMenu = MenuBuilder(context)
init { init {
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
contentView = LayoutInflater.from(context).inflate(R.layout.popup_action_menu, null) contentView = binding.root
isTouchable = true isTouchable = true
isOutsideTouchable = false isOutsideTouchable = false
@ -52,54 +52,55 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
initRecyclerView() initRecyclerView()
setOnDismissListener { setOnDismissListener {
contentView.apply { contentView.apply {
iv_menu_more.setImageResource(R.drawable.ic_more_vert) binding.ivMenuMore.setImageResource(R.drawable.ic_more_vert)
recycler_view_more.gone() binding.recyclerViewMore.gone()
adapter.setItems(menu.visibleItems) adapter.setItems(menu.visibleItems)
recycler_view.visible() binding.recyclerView.visible()
} }
} }
} }
private fun initRecyclerView() = with(contentView) { private fun initRecyclerView() = with(contentView) {
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
recycler_view_more.adapter = adapter binding.recyclerViewMore.adapter = adapter
SupportMenuInflater(context).inflate(R.menu.content_select_action, menu) SupportMenuInflater(context).inflate(R.menu.content_select_action, menu)
adapter.setItems(menu.visibleItems) adapter.setItems(menu.visibleItems)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
onInitializeMenu(moreMenu) onInitializeMenu(moreMenu)
} }
if (moreMenu.size() > 0) { if (moreMenu.size() > 0) {
iv_menu_more.visible() binding.ivMenuMore.visible()
} }
iv_menu_more.onClick { binding.ivMenuMore.onClick {
if (recycler_view.isVisible) { if (binding.recyclerView.isVisible) {
iv_menu_more.setImageResource(R.drawable.ic_arrow_back) binding.ivMenuMore.setImageResource(R.drawable.ic_arrow_back)
adapter.setItems(moreMenu.visibleItems) adapter.setItems(moreMenu.visibleItems)
recycler_view.gone() binding.recyclerView.gone()
recycler_view_more.visible() binding.recyclerViewMore.visible()
} else { } else {
iv_menu_more.setImageResource(R.drawable.ic_more_vert) binding.ivMenuMore.setImageResource(R.drawable.ic_more_vert)
recycler_view_more.gone() binding.recyclerViewMore.gone()
adapter.setItems(menu.visibleItems) adapter.setItems(menu.visibleItems)
recycler_view.visible() binding.recyclerView.visible()
} }
} }
} }
inner class Adapter(context: Context) : inner class Adapter(context: Context) :
SimpleRecyclerAdapter<MenuItemImpl>(context, R.layout.item_text) { SimpleRecyclerAdapter<MenuItemImpl, ItemTextBinding>(context) {
override fun convert( override fun convert(
holder: ItemViewHolder, holder: ItemViewHolder,
binding: ItemTextBinding,
item: MenuItemImpl, item: MenuItemImpl,
payloads: MutableList<Any> payloads: MutableList<Any>
) { ) {
with(holder.itemView) { with(binding) {
text_view.text = item.title textView.text = item.title
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemTextBinding) {
holder.itemView.onClick { holder.itemView.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
if (!callBack.onMenuItemSelected(it.itemId)) { if (!callBack.onMenuItemSelected(it.itemId)) {

@ -6,6 +6,7 @@ import android.view.*
import android.widget.SeekBar import android.widget.SeekBar
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.databinding.DialogAutoReadBinding
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.bottomBackground
import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.getPrimaryTextColor
@ -13,12 +14,14 @@ import io.legado.app.service.BaseReadAloudService
import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadAloud
import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.utils.ColorUtils import io.legado.app.utils.ColorUtils
import kotlinx.android.synthetic.main.dialog_auto_read.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class AutoReadDialog : BaseDialogFragment() { class AutoReadDialog : BaseDialogFragment() {
var callBack: CallBack? = null var callBack: CallBack? = null
private val binding by viewBinding(DialogAutoReadBinding::bind)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
dialog?.window?.let { dialog?.window?.let {
@ -52,17 +55,17 @@ class AutoReadDialog : BaseDialogFragment() {
val bg = requireContext().bottomBackground val bg = requireContext().bottomBackground
val isLight = ColorUtils.isColorLight(bg) val isLight = ColorUtils.isColorLight(bg)
val textColor = requireContext().getPrimaryTextColor(isLight) val textColor = requireContext().getPrimaryTextColor(isLight)
root_view.setBackgroundColor(bg) binding.root.setBackgroundColor(bg)
tv_read_speed_title.setTextColor(textColor) binding.tvReadSpeedTitle.setTextColor(textColor)
tv_read_speed.setTextColor(textColor) binding.tvReadSpeed.setTextColor(textColor)
iv_catalog.setColorFilter(textColor) binding.ivCatalog.setColorFilter(textColor)
tv_catalog.setTextColor(textColor) binding.tvCatalog.setTextColor(textColor)
iv_main_menu.setColorFilter(textColor) binding.ivMainMenu.setColorFilter(textColor)
tv_main_menu.setTextColor(textColor) binding.tvMainMenu.setTextColor(textColor)
iv_auto_page_stop.setColorFilter(textColor) binding.ivAutoPageStop.setColorFilter(textColor)
tv_auto_page_stop.setTextColor(textColor) binding.tvAutoPageStop.setTextColor(textColor)
iv_setting.setColorFilter(textColor) binding.ivSetting.setColorFilter(textColor)
tv_setting.setTextColor(textColor) binding.tvSetting.setTextColor(textColor)
initOnChange() initOnChange()
initData() initData()
initEvent() initEvent()
@ -70,34 +73,34 @@ class AutoReadDialog : BaseDialogFragment() {
private fun initData() { private fun initData() {
val speed = if (ReadBookConfig.autoReadSpeed < 10) 10 else ReadBookConfig.autoReadSpeed val speed = if (ReadBookConfig.autoReadSpeed < 10) 10 else ReadBookConfig.autoReadSpeed
tv_read_speed.text = String.format("%ds", speed) binding.tvReadSpeed.text = String.format("%ds", speed)
seek_auto_read.progress = speed binding.seekAutoRead.progress = speed
} }
private fun initOnChange() { private fun initOnChange() {
seek_auto_read.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { binding.seekAutoRead.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
val speed = if (progress < 10) 10 else progress val speed = if (progress < 10) 10 else progress
tv_read_speed.text = String.format("%ds", speed) binding.tvReadSpeed.text = String.format("%ds", speed)
} }
override fun onStartTrackingTouch(seekBar: SeekBar) = Unit override fun onStartTrackingTouch(seekBar: SeekBar) = Unit
override fun onStopTrackingTouch(seekBar: SeekBar) { override fun onStopTrackingTouch(seekBar: SeekBar) {
ReadBookConfig.autoReadSpeed = ReadBookConfig.autoReadSpeed =
if (seek_auto_read.progress < 10) 10 else seek_auto_read.progress if (binding.seekAutoRead.progress < 10) 10 else binding.seekAutoRead.progress
upTtsSpeechRate() upTtsSpeechRate()
} }
}) })
} }
private fun initEvent() { private fun initEvent() {
ll_main_menu.onClick { callBack?.showMenuBar(); dismiss() } binding.llMainMenu.onClick { callBack?.showMenuBar(); dismiss() }
ll_setting.onClick { binding.llSetting.onClick {
ReadAloudConfigDialog().show(childFragmentManager, "readAloudConfigDialog") ReadAloudConfigDialog().show(childFragmentManager, "readAloudConfigDialog")
} }
ll_catalog.onClick { callBack?.openChapterList() } binding.llCatalog.onClick { callBack?.openChapterList() }
ll_auto_page_stop.onClick { binding.llAutoPageStop.onClick {
callBack?.autoPageStop() callBack?.autoPageStop()
dismiss() dismiss()
} }

@ -1,34 +1,38 @@
package io.legado.app.ui.book.read.config package io.legado.app.ui.book.read.config
import android.content.Context import android.content.Context
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.databinding.ItemBgImageBinding
import io.legado.app.help.ImageLoader import io.legado.app.help.ImageLoader
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import kotlinx.android.synthetic.main.item_bg_image.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.io.File import java.io.File
class BgAdapter(context: Context, val textColor: Int) : class BgAdapter(context: Context, val textColor: Int) :
SimpleRecyclerAdapter<String>(context, R.layout.item_bg_image) { SimpleRecyclerAdapter<String, ItemBgImageBinding>(context) {
override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
binding: ItemBgImageBinding,
item: String,
payloads: MutableList<Any>
) {
with(binding) {
ImageLoader.load( ImageLoader.load(
context, context,
context.assets.open("bg${File.separator}$item").readBytes() context.assets.open("bg${File.separator}$item").readBytes()
) )
.centerCrop() .centerCrop()
.into(iv_bg) .into(ivBg)
tv_name.setTextColor(textColor) tvName.setTextColor(textColor)
tv_name.text = item.substringBeforeLast(".") tvName.text = item.substringBeforeLast(".")
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemBgImageBinding) {
holder.itemView.apply { holder.itemView.apply {
this.onClick { this.onClick {
getItemByLayoutPosition(holder.layoutPosition)?.let { getItemByLayoutPosition(holder.layoutPosition)?.let {

@ -13,6 +13,8 @@ import com.jaredrummler.android.colorpicker.ColorPickerDialog
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.databinding.DialogReadBgTextBinding
import io.legado.app.databinding.ItemBgImageBinding
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.help.http.HttpHelper import io.legado.app.help.http.HttpHelper
import io.legado.app.help.permission.Permissions import io.legado.app.help.permission.Permissions
@ -26,9 +28,7 @@ import io.legado.app.ui.filepicker.FilePicker
import io.legado.app.ui.filepicker.FilePickerDialog import io.legado.app.ui.filepicker.FilePickerDialog
import io.legado.app.ui.widget.text.AutoCompleteTextView import io.legado.app.ui.widget.text.AutoCompleteTextView
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.dialog_read_bg_text.*
import kotlinx.android.synthetic.main.item_bg_image.view.*
import org.jetbrains.anko.sdk27.listeners.onCheckedChange import org.jetbrains.anko.sdk27.listeners.onCheckedChange
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.io.File import java.io.File
@ -40,6 +40,7 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
const val BG_COLOR = 122 const val BG_COLOR = 122
} }
private val binding by viewBinding(DialogReadBgTextBinding::bind)
private val requestCodeBg = 123 private val requestCodeBg = 123
private val requestCodeExport = 131 private val requestCodeExport = 131
private val requestCodeImport = 132 private val requestCodeImport = 132
@ -88,28 +89,31 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
val isLight = ColorUtils.isColorLight(bg) val isLight = ColorUtils.isColorLight(bg)
primaryTextColor = requireContext().getPrimaryTextColor(isLight) primaryTextColor = requireContext().getPrimaryTextColor(isLight)
secondaryTextColor = requireContext().getSecondaryTextColor(isLight) secondaryTextColor = requireContext().getSecondaryTextColor(isLight)
root_view.setBackgroundColor(bg) binding.rootView.setBackgroundColor(bg)
sw_dark_status_icon.setTextColor(primaryTextColor) binding.swDarkStatusIcon.setTextColor(primaryTextColor)
iv_import.setColorFilter(primaryTextColor) binding.ivImport.setColorFilter(primaryTextColor)
iv_export.setColorFilter(primaryTextColor) binding.ivExport.setColorFilter(primaryTextColor)
iv_delete.setColorFilter(primaryTextColor) binding.ivDelete.setColorFilter(primaryTextColor)
tv_bg_image.setTextColor(primaryTextColor) binding.tvBgImage.setTextColor(primaryTextColor)
} }
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun initData() = with(ReadBookConfig.durConfig) { private fun initData() = with(ReadBookConfig.durConfig) {
tv_name.text = name.ifBlank { "文字" } binding.tvName.text = name.ifBlank { "文字" }
sw_dark_status_icon.isChecked = curStatusIconDark() binding.swDarkStatusIcon.isChecked = curStatusIconDark()
adapter = BgAdapter(requireContext(), secondaryTextColor) adapter = BgAdapter(requireContext(), secondaryTextColor)
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
val headerView = LayoutInflater.from(requireContext()) val headerView = ItemBgImageBinding.inflate(
.inflate(R.layout.item_bg_image, recycler_view, false) LayoutInflater.from(requireContext()),
binding.recyclerView,
false
)
adapter.addHeaderView(headerView) adapter.addHeaderView(headerView)
headerView.tv_name.setTextColor(secondaryTextColor) headerView.tvName.setTextColor(secondaryTextColor)
headerView.tv_name.text = getString(R.string.select_image) headerView.tvName.text = getString(R.string.select_image)
headerView.iv_bg.setImageResource(R.drawable.ic_image) headerView.ivBg.setImageResource(R.drawable.ic_image)
headerView.iv_bg.setColorFilter(primaryTextColor) headerView.ivBg.setColorFilter(primaryTextColor)
headerView.onClick { selectImage() } headerView.root.onClick { selectImage() }
requireContext().assets.list("bg")?.let { requireContext().assets.list("bg")?.let {
adapter.setItems(it.toList()) adapter.setItems(it.toList())
} }
@ -117,31 +121,31 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun initEvent() = with(ReadBookConfig.durConfig) { private fun initEvent() = with(ReadBookConfig.durConfig) {
iv_edit.onClick { binding.ivEdit.onClick {
alert(R.string.style_name) { alert(R.string.style_name) {
var editText: AutoCompleteTextView? = null var editText: AutoCompleteTextView? = null
customView { customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
edit_view.setText(ReadBookConfig.durConfig.name) editText = findViewById(R.id.edit_view)
editText = edit_view editText!!.setText(ReadBookConfig.durConfig.name)
} }
} }
okButton { okButton {
editText?.text?.toString()?.let { editText?.text?.toString()?.let {
tv_name.text = it binding.tvName.text = it
ReadBookConfig.durConfig.name = it ReadBookConfig.durConfig.name = it
} }
} }
cancelButton() cancelButton()
}.show() }.show()
} }
sw_dark_status_icon.onCheckedChange { buttonView, isChecked -> binding.swDarkStatusIcon.onCheckedChange { buttonView, isChecked ->
if (buttonView?.isPressed == true) { if (buttonView?.isPressed == true) {
setCurStatusIconDark(isChecked) setCurStatusIconDark(isChecked)
(activity as? ReadBookActivity)?.upSystemUiVisibility() (activity as? ReadBookActivity)?.upSystemUiVisibility()
} }
} }
tv_text_color.onClick { binding.tvTextColor.onClick {
ColorPickerDialog.newBuilder() ColorPickerDialog.newBuilder()
.setColor(curTextColor()) .setColor(curTextColor())
.setShowAlphaSlider(false) .setShowAlphaSlider(false)
@ -149,7 +153,7 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
.setDialogId(TEXT_COLOR) .setDialogId(TEXT_COLOR)
.show(requireActivity()) .show(requireActivity())
} }
tv_bg_color.onClick { binding.tvBgColor.onClick {
val bgColor = val bgColor =
if (curBgType() == 0) Color.parseColor(curBgStr()) if (curBgType() == 0) Color.parseColor(curBgStr())
else Color.parseColor("#015A86") else Color.parseColor("#015A86")
@ -160,7 +164,7 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
.setDialogId(BG_COLOR) .setDialogId(BG_COLOR)
.show(requireActivity()) .show(requireActivity())
} }
iv_import.onClick { binding.ivImport.onClick {
val importFormNet = "网络导入" val importFormNet = "网络导入"
val otherActions = arrayListOf(importFormNet) val otherActions = arrayListOf(importFormNet)
FilePicker.selectFile( FilePicker.selectFile(
@ -175,14 +179,14 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
} }
} }
} }
iv_export.onClick { binding.ivExport.onClick {
FilePicker.selectFolder( FilePicker.selectFolder(
this@BgTextConfigDialog, this@BgTextConfigDialog,
requestCodeExport, requestCodeExport,
title = getString(R.string.export_str) title = getString(R.string.export_str)
) )
} }
iv_delete.onClick { binding.ivDelete.onClick {
if (ReadBookConfig.deleteDur()) { if (ReadBookConfig.deleteDur()) {
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
dismiss() dismiss()
@ -277,7 +281,7 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
var editText: AutoCompleteTextView? = null var editText: AutoCompleteTextView? = null
customView { customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view editText = findViewById(R.id.edit_view)
} }
} }
okButton { okButton {

@ -9,16 +9,17 @@ import android.widget.TextView
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.databinding.DialogClickActionConfigBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.lib.dialogs.selector import io.legado.app.lib.dialogs.selector
import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.utils.getCompatColor import io.legado.app.utils.getCompatColor
import io.legado.app.utils.putPrefInt import io.legado.app.utils.putPrefInt
import kotlinx.android.synthetic.main.dialog_click_action_config.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class ClickActionConfigDialog : BaseDialogFragment() { class ClickActionConfigDialog : BaseDialogFragment() {
private val binding by viewBinding(DialogClickActionConfigBinding::bind)
private val actions = linkedMapOf<Int, String>() private val actions = linkedMapOf<Int, String>()
override fun onStart() { override fun onStart() {
@ -56,63 +57,63 @@ class ClickActionConfigDialog : BaseDialogFragment() {
} }
private fun initData() = with(AppConfig) { private fun initData() = with(AppConfig) {
tv_top_left.text = actions[clickActionTL] binding.tvTopLeft.text = actions[clickActionTL]
tv_top_center.text = actions[clickActionTC] binding.tvTopCenter.text = actions[clickActionTC]
tv_top_right.text = actions[clickActionTR] binding.tvTopRight.text = actions[clickActionTR]
tv_middle_left.text = actions[clickActionML] binding.tvMiddleLeft.text = actions[clickActionML]
tv_middle_right.text = actions[clickActionMR] binding.tvMiddleRight.text = actions[clickActionMR]
tv_bottom_left.text = actions[clickActionBL] binding.tvBottomLeft.text = actions[clickActionBL]
tv_bottom_center.text = actions[clickActionBC] binding.tvBottomCenter.text = actions[clickActionBC]
tv_bottom_right.text = actions[clickActionBR] binding.tvBottomRight.text = actions[clickActionBR]
} }
private fun initViewEvent() { private fun initViewEvent() {
iv_close.onClick { binding.ivClose.onClick {
dismiss() dismiss()
} }
tv_top_left.onClick { binding.tvTopLeft.onClick {
selectAction { action -> selectAction { action ->
putPrefInt(PreferKey.clickActionTL, action) putPrefInt(PreferKey.clickActionTL, action)
(it as? TextView)?.text = actions[action] (it as? TextView)?.text = actions[action]
} }
} }
tv_top_center.onClick { binding.tvTopCenter.onClick {
selectAction { action -> selectAction { action ->
putPrefInt(PreferKey.clickActionTC, action) putPrefInt(PreferKey.clickActionTC, action)
(it as? TextView)?.text = actions[action] (it as? TextView)?.text = actions[action]
} }
} }
tv_top_right.onClick { binding.tvTopRight.onClick {
selectAction { action -> selectAction { action ->
putPrefInt(PreferKey.clickActionTR, action) putPrefInt(PreferKey.clickActionTR, action)
(it as? TextView)?.text = actions[action] (it as? TextView)?.text = actions[action]
} }
} }
tv_middle_left.onClick { binding.tvMiddleLeft.onClick {
selectAction { action -> selectAction { action ->
putPrefInt(PreferKey.clickActionML, action) putPrefInt(PreferKey.clickActionML, action)
(it as? TextView)?.text = actions[action] (it as? TextView)?.text = actions[action]
} }
} }
tv_middle_right.onClick { binding.tvMiddleRight.onClick {
selectAction { action -> selectAction { action ->
putPrefInt(PreferKey.clickActionMR, action) putPrefInt(PreferKey.clickActionMR, action)
(it as? TextView)?.text = actions[action] (it as? TextView)?.text = actions[action]
} }
} }
tv_bottom_left.onClick { binding.tvBottomLeft.onClick {
selectAction { action -> selectAction { action ->
putPrefInt(PreferKey.clickActionBL, action) putPrefInt(PreferKey.clickActionBL, action)
(it as? TextView)?.text = actions[action] (it as? TextView)?.text = actions[action]
} }
} }
tv_bottom_center.onClick { binding.tvBottomCenter.onClick {
selectAction { action -> selectAction { action ->
putPrefInt(PreferKey.clickActionBC, action) putPrefInt(PreferKey.clickActionBC, action)
(it as? TextView)?.text = actions[action] (it as? TextView)?.text = actions[action]
} }
} }
tv_bottom_right.onClick { binding.tvBottomRight.onClick {
selectAction { action -> selectAction { action ->
putPrefInt(PreferKey.clickActionBR, action) putPrefInt(PreferKey.clickActionBR, action)
(it as? TextView)?.text = actions[action] (it as? TextView)?.text = actions[action]

@ -9,13 +9,16 @@ import android.view.WindowManager
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.databinding.DialogReadPaddingBinding
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.utils.getSize import io.legado.app.utils.getSize
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import kotlinx.android.synthetic.main.dialog_read_padding.* import io.legado.app.utils.viewbindingdelegate.viewBinding
class PaddingConfigDialog : BaseDialogFragment() { class PaddingConfigDialog : BaseDialogFragment() {
private val binding by viewBinding(DialogReadPaddingBinding::bind)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
val dm = requireActivity().getSize() val dm = requireActivity().getSize()
@ -48,83 +51,83 @@ class PaddingConfigDialog : BaseDialogFragment() {
private fun initData() = ReadBookConfig.apply { private fun initData() = ReadBookConfig.apply {
//正文 //正文
dsb_padding_top.progress = paddingTop binding.dsbPaddingTop.progress = paddingTop
dsb_padding_bottom.progress = paddingBottom binding.dsbPaddingBottom.progress = paddingBottom
dsb_padding_left.progress = paddingLeft binding.dsbPaddingLeft.progress = paddingLeft
dsb_padding_right.progress = paddingRight binding.dsbPaddingRight.progress = paddingRight
//页眉 //页眉
dsb_header_padding_top.progress = headerPaddingTop binding.dsbHeaderPaddingTop.progress = headerPaddingTop
dsb_header_padding_bottom.progress = headerPaddingBottom binding.dsbHeaderPaddingBottom.progress = headerPaddingBottom
dsb_header_padding_left.progress = headerPaddingLeft binding.dsbHeaderPaddingLeft.progress = headerPaddingLeft
dsb_header_padding_right.progress = headerPaddingRight binding.dsbHeaderPaddingRight.progress = headerPaddingRight
//页脚 //页脚
dsb_footer_padding_top.progress = footerPaddingTop binding.dsbFooterPaddingTop.progress = footerPaddingTop
dsb_footer_padding_bottom.progress = footerPaddingBottom binding.dsbFooterPaddingBottom.progress = footerPaddingBottom
dsb_footer_padding_left.progress = footerPaddingLeft binding.dsbFooterPaddingLeft.progress = footerPaddingLeft
dsb_footer_padding_right.progress = footerPaddingRight binding.dsbFooterPaddingRight.progress = footerPaddingRight
cb_show_top_line.isChecked = showHeaderLine binding.cbShowTopLine.isChecked = showHeaderLine
cb_show_bottom_line.isChecked = showFooterLine binding.cbShowBottomLine.isChecked = showFooterLine
} }
private fun initView() = with(ReadBookConfig) { private fun initView() = with(ReadBookConfig) {
//正文 //正文
dsb_padding_top.onChanged = { binding.dsbPaddingTop.onChanged = {
paddingTop = it paddingTop = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_padding_bottom.onChanged = { binding.dsbPaddingBottom.onChanged = {
paddingBottom = it paddingBottom = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_padding_left.onChanged = { binding.dsbPaddingLeft.onChanged = {
paddingLeft = it paddingLeft = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_padding_right.onChanged = { binding.dsbPaddingRight.onChanged = {
paddingRight = it paddingRight = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
//页眉 //页眉
dsb_header_padding_top.onChanged = { binding.dsbHeaderPaddingTop.onChanged = {
headerPaddingTop = it headerPaddingTop = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_header_padding_bottom.onChanged = { binding.dsbHeaderPaddingBottom.onChanged = {
headerPaddingBottom = it headerPaddingBottom = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_header_padding_left.onChanged = { binding.dsbHeaderPaddingLeft.onChanged = {
headerPaddingLeft = it headerPaddingLeft = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_header_padding_right.onChanged = { binding.dsbHeaderPaddingRight.onChanged = {
headerPaddingRight = it headerPaddingRight = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
//页脚 //页脚
dsb_footer_padding_top.onChanged = { binding.dsbFooterPaddingTop.onChanged = {
footerPaddingTop = it footerPaddingTop = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_footer_padding_bottom.onChanged = { binding.dsbFooterPaddingBottom.onChanged = {
footerPaddingBottom = it footerPaddingBottom = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_footer_padding_left.onChanged = { binding.dsbFooterPaddingLeft.onChanged = {
footerPaddingLeft = it footerPaddingLeft = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_footer_padding_right.onChanged = { binding.dsbFooterPaddingRight.onChanged = {
footerPaddingRight = it footerPaddingRight = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
cb_show_top_line.onCheckedChangeListener = { cb, isChecked -> binding.cbShowTopLine.onCheckedChangeListener = { cb, isChecked ->
if (cb.isPressed) { if (cb.isPressed) {
showHeaderLine = isChecked showHeaderLine = isChecked
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
} }
cb_show_bottom_line.onCheckedChangeListener = { cb, isChecked -> binding.cbShowBottomLine.onCheckedChangeListener = { cb, isChecked ->
if (cb.isPressed) { if (cb.isPressed) {
showFooterLine = isChecked showFooterLine = isChecked
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)

@ -3,42 +3,45 @@ package io.legado.app.ui.book.read.config
import android.app.Dialog import android.app.Dialog
import android.content.Context import android.content.Context
import android.view.KeyEvent import android.view.KeyEvent
import android.view.LayoutInflater
import io.legado.app.R import io.legado.app.R
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.databinding.DialogPageKeyBinding
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
import io.legado.app.utils.getPrefString import io.legado.app.utils.getPrefString
import io.legado.app.utils.hideSoftInput import io.legado.app.utils.hideSoftInput
import io.legado.app.utils.putPrefString import io.legado.app.utils.putPrefString
import kotlinx.android.synthetic.main.dialog_page_key.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class PageKeyDialog(context: Context) : Dialog(context, R.style.AppTheme_AlertDialog) { class PageKeyDialog(context: Context) : Dialog(context, R.style.AppTheme_AlertDialog) {
private val binding = DialogPageKeyBinding.inflate(LayoutInflater.from(context))
init { init {
setContentView(R.layout.dialog_page_key) setContentView(binding.root)
content_view.setBackgroundColor(context.backgroundColor) binding.contentView.setBackgroundColor(context.backgroundColor)
et_prev.setText(context.getPrefString(PreferKey.prevKeys)) binding.etPrev.setText(context.getPrefString(PreferKey.prevKeys))
et_next.setText(context.getPrefString(PreferKey.nextKeys)) binding.etNext.setText(context.getPrefString(PreferKey.nextKeys))
tv_ok.onClick { binding.tvOk.onClick {
context.putPrefString(PreferKey.prevKeys, et_prev.text?.toString()) context.putPrefString(PreferKey.prevKeys, binding.etPrev.text?.toString())
context.putPrefString(PreferKey.nextKeys, et_next.text?.toString()) context.putPrefString(PreferKey.nextKeys, binding.etNext.text?.toString())
dismiss() dismiss()
} }
} }
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode != KeyEvent.KEYCODE_BACK && keyCode != KeyEvent.KEYCODE_DEL) { if (keyCode != KeyEvent.KEYCODE_BACK && keyCode != KeyEvent.KEYCODE_DEL) {
if (et_prev.hasFocus()) { if (binding.etPrev.hasFocus()) {
val editableText = et_prev.editableText val editableText = binding.etPrev.editableText
if (editableText.isEmpty() or editableText.endsWith(",")) { if (editableText.isEmpty() or editableText.endsWith(",")) {
editableText.append(keyCode.toString()) editableText.append(keyCode.toString())
} else { } else {
editableText.append(",").append(keyCode.toString()) editableText.append(",").append(keyCode.toString())
} }
return true return true
} else if (et_next.hasFocus()) { } else if (binding.etNext.hasFocus()) {
val editableText = et_next.editableText val editableText = binding.etNext.editableText
if (editableText.isEmpty() or editableText.endsWith(",")) { if (editableText.isEmpty() or editableText.endsWith(",")) {
editableText.append(keyCode.toString()) editableText.append(keyCode.toString())
} else { } else {

@ -7,6 +7,7 @@ import android.widget.SeekBar
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.databinding.DialogReadAloudBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.bottomBackground
import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.getPrimaryTextColor
@ -18,11 +19,12 @@ import io.legado.app.utils.ColorUtils
import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.observeEvent import io.legado.app.utils.observeEvent
import io.legado.app.utils.putPrefBoolean import io.legado.app.utils.putPrefBoolean
import kotlinx.android.synthetic.main.dialog_read_aloud.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class ReadAloudDialog : BaseDialogFragment() { class ReadAloudDialog : BaseDialogFragment() {
var callBack: CallBack? = null private var callBack: CallBack? = null
private val binding by viewBinding(DialogReadAloudBinding::bind)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
@ -57,59 +59,61 @@ class ReadAloudDialog : BaseDialogFragment() {
val bg = requireContext().bottomBackground val bg = requireContext().bottomBackground
val isLight = ColorUtils.isColorLight(bg) val isLight = ColorUtils.isColorLight(bg)
val textColor = requireContext().getPrimaryTextColor(isLight) val textColor = requireContext().getPrimaryTextColor(isLight)
root_view.setBackgroundColor(bg) with(binding) {
tv_pre.setTextColor(textColor) rootView.setBackgroundColor(bg)
tv_next.setTextColor(textColor) tvPre.setTextColor(textColor)
iv_play_prev.setColorFilter(textColor) tvNext.setTextColor(textColor)
iv_play_pause.setColorFilter(textColor) ivPlayPrev.setColorFilter(textColor)
iv_play_next.setColorFilter(textColor) ivPlayPause.setColorFilter(textColor)
iv_stop.setColorFilter(textColor) ivPlayNext.setColorFilter(textColor)
iv_timer.setColorFilter(textColor) ivStop.setColorFilter(textColor)
tv_timer.setTextColor(textColor) ivTimer.setColorFilter(textColor)
tv_tts_speed.setTextColor(textColor) tvTimer.setTextColor(textColor)
iv_catalog.setColorFilter(textColor) tvTtsSpeed.setTextColor(textColor)
tv_catalog.setTextColor(textColor) ivCatalog.setColorFilter(textColor)
iv_main_menu.setColorFilter(textColor) tvCatalog.setTextColor(textColor)
tv_main_menu.setTextColor(textColor) ivMainMenu.setColorFilter(textColor)
iv_to_backstage.setColorFilter(textColor) tvMainMenu.setTextColor(textColor)
tv_to_backstage.setTextColor(textColor) ivToBackstage.setColorFilter(textColor)
iv_setting.setColorFilter(textColor) tvToBackstage.setTextColor(textColor)
tv_setting.setTextColor(textColor) ivSetting.setColorFilter(textColor)
cb_tts_follow_sys.setTextColor(textColor) tvSetting.setTextColor(textColor)
cbTtsFollowSys.setTextColor(textColor)
}
initOnChange() initOnChange()
initData() initData()
initEvent() initEvent()
} }
private fun initData() { private fun initData() = with(binding) {
upPlayState() upPlayState()
upTimerText(BaseReadAloudService.timeMinute) upTimerText(BaseReadAloudService.timeMinute)
seek_timer.progress = BaseReadAloudService.timeMinute seekTimer.progress = BaseReadAloudService.timeMinute
cb_tts_follow_sys.isChecked = requireContext().getPrefBoolean("ttsFollowSys", true) cbTtsFollowSys.isChecked = requireContext().getPrefBoolean("ttsFollowSys", true)
seek_tts_SpeechRate.isEnabled = !cb_tts_follow_sys.isChecked seekTtsSpeechRate.isEnabled = !cbTtsFollowSys.isChecked
seek_tts_SpeechRate.progress = AppConfig.ttsSpeechRate seekTtsSpeechRate.progress = AppConfig.ttsSpeechRate
} }
private fun initOnChange() { private fun initOnChange() = with(binding) {
cb_tts_follow_sys.setOnCheckedChangeListener { buttonView, isChecked -> cbTtsFollowSys.setOnCheckedChangeListener { buttonView, isChecked ->
if (buttonView.isPressed) { if (buttonView.isPressed) {
requireContext().putPrefBoolean("ttsFollowSys", isChecked) requireContext().putPrefBoolean("ttsFollowSys", isChecked)
seek_tts_SpeechRate.isEnabled = !isChecked seekTtsSpeechRate.isEnabled = !isChecked
upTtsSpeechRate() upTtsSpeechRate()
} }
} }
seek_tts_SpeechRate.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { seekTtsSpeechRate.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
} }
override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit
override fun onStopTrackingTouch(seekBar: SeekBar?) { override fun onStopTrackingTouch(seekBar: SeekBar?) {
AppConfig.ttsSpeechRate = seek_tts_SpeechRate.progress AppConfig.ttsSpeechRate = seekTtsSpeechRate.progress
upTtsSpeechRate() upTtsSpeechRate()
} }
}) })
seek_timer.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { seekTimer.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
upTimerText(progress) upTimerText(progress)
} }
@ -117,40 +121,40 @@ class ReadAloudDialog : BaseDialogFragment() {
override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit
override fun onStopTrackingTouch(seekBar: SeekBar?) { override fun onStopTrackingTouch(seekBar: SeekBar?) {
ReadAloud.setTimer(requireContext(), seek_timer.progress) ReadAloud.setTimer(requireContext(), seekTimer.progress)
} }
}) })
} }
private fun initEvent() { private fun initEvent() = with(binding) {
ll_main_menu.onClick { callBack?.showMenuBar(); dismiss() } llMainMenu.onClick { callBack?.showMenuBar(); dismiss() }
ll_setting.onClick { llSetting.onClick {
ReadAloudConfigDialog().show(childFragmentManager, "readAloudConfigDialog") ReadAloudConfigDialog().show(childFragmentManager, "readAloudConfigDialog")
} }
tv_pre.onClick { ReadBook.moveToPrevChapter(upContent = true, toLast = false) } tvPre.onClick { ReadBook.moveToPrevChapter(upContent = true, toLast = false) }
tv_next.onClick { ReadBook.moveToNextChapter(true) } tvNext.onClick { ReadBook.moveToNextChapter(true) }
iv_stop.onClick { ReadAloud.stop(requireContext()); dismiss() } ivStop.onClick { ReadAloud.stop(requireContext()); dismiss() }
iv_play_pause.onClick { callBack?.onClickReadAloud() } ivPlayPause.onClick { callBack?.onClickReadAloud() }
iv_play_prev.onClick { ReadAloud.prevParagraph(requireContext()) } ivPlayPrev.onClick { ReadAloud.prevParagraph(requireContext()) }
iv_play_next.onClick { ReadAloud.nextParagraph(requireContext()) } ivPlayNext.onClick { ReadAloud.nextParagraph(requireContext()) }
ll_catalog.onClick { callBack?.openChapterList() } llCatalog.onClick { callBack?.openChapterList() }
ll_to_backstage.onClick { callBack?.finish() } llToBackstage.onClick { callBack?.finish() }
} }
private fun upPlayState() { private fun upPlayState() {
if (!BaseReadAloudService.pause) { if (!BaseReadAloudService.pause) {
iv_play_pause.setImageResource(R.drawable.ic_pause_24dp) binding.ivPlayPause.setImageResource(R.drawable.ic_pause_24dp)
} else { } else {
iv_play_pause.setImageResource(R.drawable.ic_play_24dp) binding.ivPlayPause.setImageResource(R.drawable.ic_play_24dp)
} }
val bg = requireContext().bottomBackground val bg = requireContext().bottomBackground
val isLight = ColorUtils.isColorLight(bg) val isLight = ColorUtils.isColorLight(bg)
val textColor = requireContext().getPrimaryTextColor(isLight) val textColor = requireContext().getPrimaryTextColor(isLight)
iv_play_pause.setColorFilter(textColor) binding.ivPlayPause.setColorFilter(textColor)
} }
private fun upTimerText(timeMinute: Int) { private fun upTimerText(timeMinute: Int) {
tv_timer.text = requireContext().getString(R.string.timer_m, timeMinute) binding.tvTimer.text = requireContext().getString(R.string.timer_m, timeMinute)
} }
private fun upTtsSpeechRate() { private fun upTtsSpeechRate() {
@ -163,7 +167,7 @@ class ReadAloudDialog : BaseDialogFragment() {
override fun observeLiveBus() { override fun observeLiveBus() {
observeEvent<Int>(EventBus.ALOUD_STATE) { upPlayState() } observeEvent<Int>(EventBus.ALOUD_STATE) { upPlayState() }
observeEvent<Int>(EventBus.TTS_DS) { seek_timer.progress = it } observeEvent<Int>(EventBus.TTS_DS) { binding.seekTimer.progress = it }
} }
interface CallBack { interface CallBack {

@ -9,6 +9,8 @@ import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.databinding.DialogReadBookStyleBinding
import io.legado.app.databinding.ItemReadStyleBinding
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.lib.dialogs.selector import io.legado.app.lib.dialogs.selector
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
@ -21,15 +23,13 @@ import io.legado.app.utils.ColorUtils
import io.legado.app.utils.dp import io.legado.app.utils.dp
import io.legado.app.utils.getIndexById import io.legado.app.utils.getIndexById
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import kotlinx.android.synthetic.main.activity_book_read.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.dialog_read_book_style.*
import kotlinx.android.synthetic.main.item_read_style.view.*
import org.jetbrains.anko.sdk27.listeners.onCheckedChange import org.jetbrains.anko.sdk27.listeners.onCheckedChange
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onLongClick import org.jetbrains.anko.sdk27.listeners.onLongClick
class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack { class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack {
private val binding by viewBinding(DialogReadBookStyleBinding::bind)
val callBack get() = activity as? ReadBookActivity val callBack get() = activity as? ReadBookActivity
private lateinit var styleAdapter: StyleAdapter private lateinit var styleAdapter: StyleAdapter
@ -68,55 +68,55 @@ class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack {
(activity as ReadBookActivity).bottomDialog-- (activity as ReadBookActivity).bottomDialog--
} }
private fun initView() { private fun initView() = with(binding) {
val bg = requireContext().bottomBackground val bg = requireContext().bottomBackground
val isLight = ColorUtils.isColorLight(bg) val isLight = ColorUtils.isColorLight(bg)
val textColor = requireContext().getPrimaryTextColor(isLight) val textColor = requireContext().getPrimaryTextColor(isLight)
root_view.setBackgroundColor(bg) rootView.setBackgroundColor(bg)
tv_page_anim.setTextColor(textColor) tvPageAnim.setTextColor(textColor)
tv_bg_ts.setTextColor(textColor) tvBgTs.setTextColor(textColor)
tv_share_layout.setTextColor(textColor) tvShareLayout.setTextColor(textColor)
dsb_text_size.valueFormat = { dsbTextSize.valueFormat = {
(it + 5).toString() (it + 5).toString()
} }
dsb_text_letter_spacing.valueFormat = { dsbTextLetterSpacing.valueFormat = {
((it - 50) / 100f).toString() ((it - 50) / 100f).toString()
} }
dsb_line_size.valueFormat = { ((it - 10) / 10f).toString() } dsbLineSize.valueFormat = { ((it - 10) / 10f).toString() }
dsb_paragraph_spacing.valueFormat = { (it / 10f).toString() } dsbParagraphSpacing.valueFormat = { (it / 10f).toString() }
styleAdapter = StyleAdapter() styleAdapter = StyleAdapter()
rv_style.adapter = styleAdapter rvStyle.adapter = styleAdapter
val footerView = LayoutInflater.from(requireContext()) val footerBinding =
.inflate(R.layout.item_read_style, rv_style, false) ItemReadStyleBinding.inflate(LayoutInflater.from(requireContext()), rvStyle, false)
footerView.iv_style.setPadding(6.dp, 6.dp, 6.dp, 6.dp) footerBinding.ivStyle.setPadding(6.dp, 6.dp, 6.dp, 6.dp)
footerView.iv_style.setText(null) footerBinding.ivStyle.setText(null)
footerView.iv_style.setColorFilter(textColor) footerBinding.ivStyle.setColorFilter(textColor)
footerView.iv_style.borderColor = textColor footerBinding.ivStyle.borderColor = textColor
footerView.iv_style.setImageResource(R.drawable.ic_add) footerBinding.ivStyle.setImageResource(R.drawable.ic_add)
styleAdapter.addFooterView(footerView) styleAdapter.addFooterView(footerBinding)
footerView.onClick { footerBinding.root.onClick {
ReadBookConfig.configList.add(ReadBookConfig.Config()) ReadBookConfig.configList.add(ReadBookConfig.Config())
showBgTextConfig(ReadBookConfig.configList.lastIndex) showBgTextConfig(ReadBookConfig.configList.lastIndex)
} }
} }
private fun initData() { private fun initData() {
cb_share_layout.isChecked = ReadBookConfig.shareLayout binding.cbShareLayout.isChecked = ReadBookConfig.shareLayout
upView() upView()
styleAdapter.setItems(ReadBookConfig.configList) styleAdapter.setItems(ReadBookConfig.configList)
} }
private fun initViewEvent() { private fun initViewEvent() = with(binding) {
chinese_converter.onChanged { chineseConverter.onChanged {
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
text_font_weight_converter.onChanged { textFontWeightConverter.onChanged {
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
tv_text_font.onClick { tvTextFont.onClick {
FontSelectDialog().show(childFragmentManager, "fontSelectDialog") FontSelectDialog().show(childFragmentManager, "fontSelectDialog")
} }
tv_text_indent.onClick { tvTextIndent.onClick {
selector( selector(
title = getString(R.string.text_indent), title = getString(R.string.text_indent),
items = resources.getStringArray(R.array.indent).toList() items = resources.getStringArray(R.array.indent).toList()
@ -125,38 +125,38 @@ class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack {
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
} }
tv_padding.onClick { tvPadding.onClick {
dismiss() dismiss()
callBack?.showPaddingConfig() callBack?.showPaddingConfig()
} }
tv_tip.onClick { tvTip.onClick {
TipConfigDialog().show(childFragmentManager, "tipConfigDialog") TipConfigDialog().show(childFragmentManager, "tipConfigDialog")
} }
rg_page_anim.onCheckedChange { _, checkedId -> rgPageAnim.onCheckedChange { _, checkedId ->
ReadBook.book?.setPageAnim(-1) ReadBook.book?.setPageAnim(-1)
ReadBookConfig.pageAnim = rg_page_anim.getIndexById(checkedId) ReadBookConfig.pageAnim = binding.rgPageAnim.getIndexById(checkedId)
callBack?.page_view?.upPageAnim() callBack?.upPageAnim()
} }
cb_share_layout.onCheckedChangeListener = { checkBox, isChecked -> cbShareLayout.onCheckedChangeListener = { checkBox, isChecked ->
if (checkBox.isPressed) { if (checkBox.isPressed) {
ReadBookConfig.shareLayout = isChecked ReadBookConfig.shareLayout = isChecked
upView() upView()
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
} }
dsb_text_size.onChanged = { dsbTextSize.onChanged = {
ReadBookConfig.textSize = it + 5 ReadBookConfig.textSize = it + 5
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_text_letter_spacing.onChanged = { dsbTextLetterSpacing.onChanged = {
ReadBookConfig.letterSpacing = (it - 50) / 100f ReadBookConfig.letterSpacing = (it - 50) / 100f
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_line_size.onChanged = { dsbLineSize.onChanged = {
ReadBookConfig.lineSpacingExtra = it ReadBookConfig.lineSpacingExtra = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_paragraph_spacing.onChanged = { dsbParagraphSpacing.onChanged = {
ReadBookConfig.paragraphSpacing = it ReadBookConfig.paragraphSpacing = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
@ -181,17 +181,17 @@ class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack {
return true return true
} }
private fun upView() { private fun upView() = with(binding) {
ReadBook.pageAnim().let { ReadBook.pageAnim().let {
if (it >= 0 && it < rg_page_anim.childCount) { if (it >= 0 && it < rgPageAnim.childCount) {
rg_page_anim.check(rg_page_anim[it].id) rgPageAnim.check(rgPageAnim[it].id)
} }
} }
ReadBookConfig.let { ReadBookConfig.let {
dsb_text_size.progress = it.textSize - 5 dsbTextSize.progress = it.textSize - 5
dsb_text_letter_spacing.progress = (it.letterSpacing * 100).toInt() + 50 dsbTextLetterSpacing.progress = (it.letterSpacing * 100).toInt() + 50
dsb_line_size.progress = it.lineSpacingExtra dsbLineSize.progress = it.lineSpacingExtra
dsb_paragraph_spacing.progress = it.paragraphSpacing dsbParagraphSpacing.progress = it.paragraphSpacing
} }
} }
@ -206,36 +206,37 @@ class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack {
} }
inner class StyleAdapter : inner class StyleAdapter :
SimpleRecyclerAdapter<ReadBookConfig.Config>(requireContext(), R.layout.item_read_style) { SimpleRecyclerAdapter<ReadBookConfig.Config, ItemReadStyleBinding>(requireContext()) {
override fun convert( override fun convert(
holder: ItemViewHolder, holder: ItemViewHolder,
binding: ItemReadStyleBinding,
item: ReadBookConfig.Config, item: ReadBookConfig.Config,
payloads: MutableList<Any> payloads: MutableList<Any>
) { ) {
holder.itemView.apply { binding.apply {
iv_style.setText(item.name.ifBlank { "文字" }) ivStyle.setText(item.name.ifBlank { "文字" })
iv_style.setTextColor(item.curTextColor()) ivStyle.setTextColor(item.curTextColor())
iv_style.setImageDrawable(item.curBgDrawable(100, 150)) ivStyle.setImageDrawable(item.curBgDrawable(100, 150))
if (ReadBookConfig.styleSelect == holder.layoutPosition) { if (ReadBookConfig.styleSelect == holder.layoutPosition) {
iv_style.borderColor = accentColor ivStyle.borderColor = accentColor
iv_style.setTextBold(true) ivStyle.setTextBold(true)
} else { } else {
iv_style.borderColor = item.curTextColor() ivStyle.borderColor = item.curTextColor()
iv_style.setTextBold(false) ivStyle.setTextBold(false)
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemReadStyleBinding) {
holder.itemView.apply { binding.apply {
iv_style.onClick { ivStyle.onClick {
if (iv_style.isInView) { if (ivStyle.isInView) {
changeBg(holder.layoutPosition) changeBg(holder.layoutPosition)
} }
} }
iv_style.onLongClick { ivStyle.onLongClick {
if (iv_style.isInView) { if (ivStyle.isInView) {
showBgTextConfig(holder.layoutPosition) showBgTextConfig(holder.layoutPosition)
} else { } else {
false false

@ -17,17 +17,23 @@ import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.data.entities.HttpTTS import io.legado.app.data.entities.HttpTTS
import io.legado.app.databinding.DialogHttpTtsEditBinding
import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemHttpTtsBinding
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadAloud
import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_http_tts_edit.view.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.dialog_recycler_view.*
import kotlinx.android.synthetic.main.item_http_tts.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener { class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
private val binding by viewBinding(DialogRecyclerViewBinding::bind)
lateinit var adapter: Adapter
lateinit var viewModel: SpeakEngineViewModel
private var httpTTSData: LiveData<List<HttpTTS>>? = null
var engineId = App.INSTANCE.getPrefLong(PreferKey.speakEngine)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
@ -35,11 +41,6 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt())
} }
lateinit var adapter: Adapter
lateinit var viewModel: SpeakEngineViewModel
private var httpTTSData: LiveData<List<HttpTTS>>? = null
var engineId = App.INSTANCE.getPrefLong(PreferKey.speakEngine)
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
@ -55,33 +56,33 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
initData() initData()
} }
private fun initView() { private fun initView() = with(binding) {
tool_bar.setBackgroundColor(primaryColor) toolBar.setBackgroundColor(primaryColor)
tool_bar.setTitle(R.string.speak_engine) toolBar.setTitle(R.string.speak_engine)
recycler_view.layoutManager = LinearLayoutManager(requireContext()) recyclerView.layoutManager = LinearLayoutManager(requireContext())
adapter = Adapter(requireContext()) adapter = Adapter(requireContext())
recycler_view.adapter = adapter recyclerView.adapter = adapter
tv_footer_left.setText(R.string.local_tts) tvFooterLeft.setText(R.string.local_tts)
tv_footer_left.visible() tvFooterLeft.visible()
tv_footer_left.onClick { tvFooterLeft.onClick {
removePref(PreferKey.speakEngine) removePref(PreferKey.speakEngine)
dismiss() dismiss()
} }
tv_ok.visible() tvOk.visible()
tv_ok.onClick { tvOk.onClick {
putPrefLong(PreferKey.speakEngine, engineId) putPrefLong(PreferKey.speakEngine, engineId)
dismiss() dismiss()
} }
tv_cancel.visible() tvCancel.visible()
tv_cancel.onClick { tvCancel.onClick {
dismiss() dismiss()
} }
} }
private fun initMenu() { private fun initMenu() = with(binding) {
tool_bar.inflateMenu(R.menu.speak_engine) toolBar.inflateMenu(R.menu.speak_engine)
tool_bar.menu.applyTint(requireContext()) toolBar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this) toolBar.setOnMenuItemClickListener(this@SpeakEngineDialog)
} }
private fun initData() { private fun initData() {
@ -104,20 +105,16 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun editHttpTTS(v: HttpTTS? = null) { private fun editHttpTTS(v: HttpTTS? = null) {
val httpTTS = v?.copy() ?: HttpTTS() val httpTTS = v?.copy() ?: HttpTTS()
requireContext().alert(titleResource = R.string.speak_engine) { requireContext().alert(titleResource = R.string.speak_engine) {
var rootView: View? = null val alertBinding =
customView { DialogHttpTtsEditBinding.inflate(LayoutInflater.from(requireContext()))
LayoutInflater.from(requireContext()) alertBinding.tvName.setText(httpTTS.name)
.inflate(R.layout.dialog_http_tts_edit, null).apply { alertBinding.tvUrl.setText(httpTTS.url)
rootView = this customView = alertBinding.root
tv_name.setText(httpTTS.name)
tv_url.setText(httpTTS.url)
}
}
cancelButton() cancelButton()
okButton { okButton {
rootView?.apply { alertBinding.apply {
httpTTS.name = tv_name.text.toString() httpTTS.name = tvName.text.toString()
httpTTS.url = tv_url.text.toString() httpTTS.url = tvUrl.text.toString()
App.db.httpTTSDao().insert(httpTTS) App.db.httpTTSDao().insert(httpTTS)
ReadAloud.upReadAloudClass() ReadAloud.upReadAloudClass()
} }
@ -132,27 +129,32 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
} }
inner class Adapter(context: Context) : inner class Adapter(context: Context) :
SimpleRecyclerAdapter<HttpTTS>(context, R.layout.item_http_tts) { SimpleRecyclerAdapter<HttpTTS, ItemHttpTtsBinding>(context) {
override fun convert(holder: ItemViewHolder, item: HttpTTS, payloads: MutableList<Any>) { override fun convert(
holder.itemView.apply { holder: ItemViewHolder,
cb_name.text = item.name binding: ItemHttpTtsBinding,
cb_name.isChecked = item.id == engineId item: HttpTTS,
payloads: MutableList<Any>
) {
binding.apply {
cbName.text = item.name
cbName.isChecked = item.id == engineId
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemHttpTtsBinding) {
holder.itemView.apply { binding.apply {
cb_name.onClick { cbName.onClick {
getItem(holder.layoutPosition)?.let { httpTTS -> getItem(holder.layoutPosition)?.let { httpTTS ->
engineId = httpTTS.id engineId = httpTTS.id
notifyItemRangeChanged(0, getActualItemCount()) notifyItemRangeChanged(0, getActualItemCount())
} }
} }
iv_edit.onClick { ivEdit.onClick {
editHttpTTS(getItem(holder.layoutPosition)) editHttpTTS(getItem(holder.layoutPosition))
} }
iv_menu_delete.onClick { ivMenuDelete.onClick {
getItem(holder.layoutPosition)?.let { httpTTS -> getItem(holder.layoutPosition)?.let { httpTTS ->
App.db.httpTTSDao().delete(httpTTS) App.db.httpTTSDao().delete(httpTTS)
} }

@ -8,11 +8,12 @@ import com.jaredrummler.android.colorpicker.ColorPickerDialog
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.databinding.DialogTipConfigBinding
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.help.ReadTipConfig import io.legado.app.help.ReadTipConfig
import io.legado.app.lib.dialogs.selector import io.legado.app.lib.dialogs.selector
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_tip_config.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import org.jetbrains.anko.sdk27.listeners.onCheckedChange import org.jetbrains.anko.sdk27.listeners.onCheckedChange
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
@ -22,6 +23,8 @@ class TipConfigDialog : BaseDialogFragment() {
const val TIP_COLOR = 7897 const val TIP_COLOR = 7897
} }
private val binding by viewBinding(DialogTipConfigBinding::bind)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
dialog?.window dialog?.window
@ -44,27 +47,27 @@ class TipConfigDialog : BaseDialogFragment() {
} }
} }
private fun initView() { private fun initView() = with(binding) {
rg_title_mode.checkByIndex(ReadBookConfig.titleMode) rgTitleMode.checkByIndex(ReadBookConfig.titleMode)
dsb_title_size.progress = ReadBookConfig.titleSize dsbTitleSize.progress = ReadBookConfig.titleSize
dsb_title_top.progress = ReadBookConfig.titleTopSpacing dsbTitleTop.progress = ReadBookConfig.titleTopSpacing
dsb_title_bottom.progress = ReadBookConfig.titleBottomSpacing dsbTitleBottom.progress = ReadBookConfig.titleBottomSpacing
tv_header_show.text = ReadTipConfig.headerModes[ReadTipConfig.headerMode] tvHeaderShow.text = ReadTipConfig.headerModes[ReadTipConfig.headerMode]
tv_footer_show.text = ReadTipConfig.footerModes[ReadTipConfig.footerMode] tvFooterShow.text = ReadTipConfig.footerModes[ReadTipConfig.footerMode]
tv_header_left.text = ReadTipConfig.tipHeaderLeftStr tvHeaderLeft.text = ReadTipConfig.tipHeaderLeftStr
tv_header_middle.text = ReadTipConfig.tipHeaderMiddleStr tvHeaderMiddle.text = ReadTipConfig.tipHeaderMiddleStr
tv_header_right.text = ReadTipConfig.tipHeaderRightStr tvHeaderRight.text = ReadTipConfig.tipHeaderRightStr
tv_footer_left.text = ReadTipConfig.tipFooterLeftStr tvFooterLeft.text = ReadTipConfig.tipFooterLeftStr
tv_footer_middle.text = ReadTipConfig.tipFooterMiddleStr tvFooterMiddle.text = ReadTipConfig.tipFooterMiddleStr
tv_footer_right.text = ReadTipConfig.tipFooterRightStr tvFooterRight.text = ReadTipConfig.tipFooterRightStr
upTvTipColor() upTvTipColor()
} }
private fun upTvTipColor() { private fun upTvTipColor() {
tv_tip_color.text = binding.tvTipColor.text =
if (ReadTipConfig.tipColor == 0) { if (ReadTipConfig.tipColor == 0) {
"跟随正文" "跟随正文"
} else { } else {
@ -72,86 +75,86 @@ class TipConfigDialog : BaseDialogFragment() {
} }
} }
private fun initEvent() { private fun initEvent() = with(binding) {
rg_title_mode.onCheckedChange { _, checkedId -> rgTitleMode.onCheckedChange { _, checkedId ->
ReadBookConfig.titleMode = rg_title_mode.getIndexById(checkedId) ReadBookConfig.titleMode = rgTitleMode.getIndexById(checkedId)
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_title_size.onChanged = { dsbTitleSize.onChanged = {
ReadBookConfig.titleSize = it ReadBookConfig.titleSize = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_title_top.onChanged = { dsbTitleTop.onChanged = {
ReadBookConfig.titleTopSpacing = it ReadBookConfig.titleTopSpacing = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
dsb_title_bottom.onChanged = { dsbTitleBottom.onChanged = {
ReadBookConfig.titleBottomSpacing = it ReadBookConfig.titleBottomSpacing = it
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
ll_header_show.onClick { llHeaderShow.onClick {
selector(items = ReadTipConfig.headerModes.values.toList()) { _, i -> selector(items = ReadTipConfig.headerModes.values.toList()) { _, i ->
ReadTipConfig.headerMode = ReadTipConfig.headerModes.keys.toList()[i] ReadTipConfig.headerMode = ReadTipConfig.headerModes.keys.toList()[i]
tv_header_show.text = ReadTipConfig.headerModes[ReadTipConfig.headerMode] tvHeaderShow.text = ReadTipConfig.headerModes[ReadTipConfig.headerMode]
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
} }
ll_footer_show.onClick { llFooterShow.onClick {
selector(items = ReadTipConfig.footerModes.values.toList()) { _, i -> selector(items = ReadTipConfig.footerModes.values.toList()) { _, i ->
ReadTipConfig.footerMode = ReadTipConfig.footerModes.keys.toList()[i] ReadTipConfig.footerMode = ReadTipConfig.footerModes.keys.toList()[i]
tv_footer_show.text = ReadTipConfig.footerModes[ReadTipConfig.footerMode] tvFooterShow.text = ReadTipConfig.footerModes[ReadTipConfig.footerMode]
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
} }
ll_header_left.onClick { llHeaderLeft.onClick {
selector(items = ReadTipConfig.tips) { _, i -> selector(items = ReadTipConfig.tips) { _, i ->
clearRepeat(i) clearRepeat(i)
ReadTipConfig.tipHeaderLeft = i ReadTipConfig.tipHeaderLeft = i
tv_header_left.text = ReadTipConfig.tips[i] tvHeaderLeft.text = ReadTipConfig.tips[i]
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
} }
ll_header_middle.onClick { llHeaderMiddle.onClick {
selector(items = ReadTipConfig.tips) { _, i -> selector(items = ReadTipConfig.tips) { _, i ->
clearRepeat(i) clearRepeat(i)
ReadTipConfig.tipHeaderMiddle = i ReadTipConfig.tipHeaderMiddle = i
tv_header_middle.text = ReadTipConfig.tips[i] tvHeaderMiddle.text = ReadTipConfig.tips[i]
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
} }
ll_header_right.onClick { llHeaderRight.onClick {
selector(items = ReadTipConfig.tips) { _, i -> selector(items = ReadTipConfig.tips) { _, i ->
clearRepeat(i) clearRepeat(i)
ReadTipConfig.tipHeaderRight = i ReadTipConfig.tipHeaderRight = i
tv_header_right.text = ReadTipConfig.tips[i] tvHeaderRight.text = ReadTipConfig.tips[i]
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
} }
ll_footer_left.onClick { llFooterLeft.onClick {
selector(items = ReadTipConfig.tips) { _, i -> selector(items = ReadTipConfig.tips) { _, i ->
clearRepeat(i) clearRepeat(i)
ReadTipConfig.tipFooterLeft = i ReadTipConfig.tipFooterLeft = i
tv_footer_left.text = ReadTipConfig.tips[i] tvFooterLeft.text = ReadTipConfig.tips[i]
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
} }
ll_footer_middle.onClick { llFooterMiddle.onClick {
selector(items = ReadTipConfig.tips) { _, i -> selector(items = ReadTipConfig.tips) { _, i ->
clearRepeat(i) clearRepeat(i)
ReadTipConfig.tipFooterMiddle = i ReadTipConfig.tipFooterMiddle = i
tv_footer_middle.text = ReadTipConfig.tips[i] tvFooterMiddle.text = ReadTipConfig.tips[i]
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
} }
ll_footer_right.onClick { llFooterRight.onClick {
selector(items = ReadTipConfig.tips) { _, i -> selector(items = ReadTipConfig.tips) { _, i ->
clearRepeat(i) clearRepeat(i)
ReadTipConfig.tipFooterRight = i ReadTipConfig.tipFooterRight = i
tv_footer_right.text = ReadTipConfig.tips[i] tvFooterRight.text = ReadTipConfig.tips[i]
postEvent(EventBus.UP_CONFIG, true) postEvent(EventBus.UP_CONFIG, true)
} }
} }
ll_tip_color.onClick { llTipColor.onClick {
selector(items = arrayListOf("跟随正文", "自定义")) { _, i -> selector(items = arrayListOf("跟随正文", "自定义")) { _, i ->
when (i) { when (i) {
0 -> { 0 -> {
@ -173,27 +176,27 @@ class TipConfigDialog : BaseDialogFragment() {
if (repeat != none) { if (repeat != none) {
if (tipHeaderLeft == repeat) { if (tipHeaderLeft == repeat) {
tipHeaderLeft = none tipHeaderLeft = none
tv_header_left.text = tips[none] binding.tvHeaderLeft.text = tips[none]
} }
if (tipHeaderMiddle == repeat) { if (tipHeaderMiddle == repeat) {
tipHeaderMiddle = none tipHeaderMiddle = none
tv_header_middle.text = tips[none] binding.tvHeaderMiddle.text = tips[none]
} }
if (tipHeaderRight == repeat) { if (tipHeaderRight == repeat) {
tipHeaderRight = none tipHeaderRight = none
tv_header_right.text = tips[none] binding.tvHeaderRight.text = tips[none]
} }
if (tipFooterLeft == repeat) { if (tipFooterLeft == repeat) {
tipFooterLeft = none tipFooterLeft = none
tv_footer_left.text = tips[none] binding.tvFooterLeft.text = tips[none]
} }
if (tipFooterMiddle == repeat) { if (tipFooterMiddle == repeat) {
tipFooterMiddle = none tipFooterMiddle = none
tv_footer_middle.text = tips[none] binding.tvFooterMiddle.text = tips[none]
} }
if (tipFooterRight == repeat) { if (tipFooterRight == repeat) {
tipFooterRight = none tipFooterRight = none
tv_footer_right.text = tips[none] binding.tvFooterRight.text = tips[none]
} }
} }
} }

@ -20,17 +20,17 @@ import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.TxtTocRule import io.legado.app.data.entities.TxtTocRule
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.DialogTocRegexBinding
import io.legado.app.databinding.DialogTocRegexEditBinding
import io.legado.app.databinding.ItemTocRegexBinding
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.ui.widget.text.AutoCompleteTextView
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.dialog_toc_regex.*
import kotlinx.android.synthetic.main.dialog_toc_regex_edit.view.*
import kotlinx.android.synthetic.main.item_toc_regex.view.*
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
@ -44,6 +44,7 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
var selectedName: String? = null var selectedName: String? = null
private var durRegex: String? = null private var durRegex: String? = null
lateinit var viewModel: TocRegexViewModel lateinit var viewModel: TocRegexViewModel
private val binding by viewBinding(DialogTocRegexBinding::bind)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
@ -61,28 +62,28 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
} }
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
durRegex = arguments?.getString("tocRegex") durRegex = arguments?.getString("tocRegex")
tool_bar.setTitle(R.string.txt_toc_regex) binding.toolBar.setTitle(R.string.txt_toc_regex)
tool_bar.inflateMenu(R.menu.txt_toc_regex) binding.toolBar.inflateMenu(R.menu.txt_toc_regex)
tool_bar.menu.applyTint(requireContext()) binding.toolBar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this) binding.toolBar.setOnMenuItemClickListener(this)
initView() initView()
initData() initData()
} }
private fun initView() { private fun initView() = with(binding) {
adapter = TocRegexAdapter(requireContext()) adapter = TocRegexAdapter(requireContext())
recycler_view.layoutManager = LinearLayoutManager(requireContext()) recyclerView.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(VerticalDivider(requireContext())) recyclerView.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter recyclerView.adapter = adapter
val itemTouchCallback = ItemTouchCallback(adapter) val itemTouchCallback = ItemTouchCallback(adapter)
itemTouchCallback.isCanDrag = true itemTouchCallback.isCanDrag = true
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(recycler_view) ItemTouchHelper(itemTouchCallback).attachToRecyclerView(recyclerView)
tv_cancel.onClick { tvCancel.onClick {
dismiss() dismiss()
} }
tv_ok.onClick { tvOk.onClick {
adapter.getItems().forEach { tocRule -> adapter.getItems().forEach { tocRule ->
if (selectedName == tocRule.name) { if (selectedName == tocRule.name) {
val callBack = activity as? CallBack val callBack = activity as? CallBack
@ -139,27 +140,26 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
cacheUrls.add(0, defaultUrl) cacheUrls.add(0, defaultUrl)
} }
requireContext().alert(titleResource = R.string.import_book_source_on_line) { requireContext().alert(titleResource = R.string.import_book_source_on_line) {
var editText: AutoCompleteTextView? = null val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
customView { alertBinding.apply {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { editView.setFilterValues(cacheUrls)
editText = this.edit_view editView.delCallBack = {
edit_view.setFilterValues(cacheUrls) cacheUrls.remove(it)
edit_view.delCallBack = { aCache.put(importTocRuleKey, cacheUrls.joinToString(","))
cacheUrls.remove(it)
aCache.put(importTocRuleKey, cacheUrls.joinToString(","))
}
} }
} }
customView = alertBinding.root
okButton { okButton {
val text = editText?.text?.toString() val text = alertBinding.editView.text?.toString()
text?.let { text?.let {
if (!cacheUrls.contains(it)) { if (!cacheUrls.contains(it)) {
cacheUrls.add(0, it) cacheUrls.add(0, it)
aCache.put(importTocRuleKey, cacheUrls.joinToString(",")) aCache.put(importTocRuleKey, cacheUrls.joinToString(","))
} }
Snackbar.make(tool_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE).show() Snackbar.make(binding.toolBar, R.string.importing, Snackbar.LENGTH_INDEFINITE)
.show()
viewModel.importOnLine(it) { msg -> viewModel.importOnLine(it) { msg ->
tool_bar.snackbar(msg) binding.toolBar.snackbar(msg)
} }
} }
} }
@ -171,19 +171,16 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
private fun editRule(rule: TxtTocRule? = null) { private fun editRule(rule: TxtTocRule? = null) {
val tocRule = rule?.copy() ?: TxtTocRule() val tocRule = rule?.copy() ?: TxtTocRule()
requireContext().alert(titleResource = R.string.txt_toc_regex) { requireContext().alert(titleResource = R.string.txt_toc_regex) {
var rootView: View? = null val alertBinding = DialogTocRegexEditBinding.inflate(layoutInflater)
customView { alertBinding.apply {
LayoutInflater.from(requireContext()) tvRuleName.setText(tocRule.name)
.inflate(R.layout.dialog_toc_regex_edit, null).apply { tvRuleRegex.setText(tocRule.rule)
rootView = this
tv_rule_name.setText(tocRule.name)
tv_rule_regex.setText(tocRule.rule)
}
} }
customView = alertBinding.root
okButton { okButton {
rootView?.apply { alertBinding.apply {
tocRule.name = tv_rule_name.text.toString() tocRule.name = tvRuleName.text.toString()
tocRule.rule = tv_rule_regex.text.toString() tocRule.rule = tvRuleRegex.text.toString()
viewModel.saveRule(tocRule) viewModel.saveRule(tocRule)
} }
} }
@ -192,31 +189,36 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
} }
inner class TocRegexAdapter(context: Context) : inner class TocRegexAdapter(context: Context) :
SimpleRecyclerAdapter<TxtTocRule>(context, R.layout.item_toc_regex), SimpleRecyclerAdapter<TxtTocRule, ItemTocRegexBinding>(context),
ItemTouchCallback.Callback { ItemTouchCallback.Callback {
override fun convert(holder: ItemViewHolder, item: TxtTocRule, payloads: MutableList<Any>) { override fun convert(
holder.itemView.apply { holder: ItemViewHolder,
binding: ItemTocRegexBinding,
item: TxtTocRule,
payloads: MutableList<Any>
) {
binding.apply {
if (payloads.isEmpty()) { if (payloads.isEmpty()) {
setBackgroundColor(context.backgroundColor) root.setBackgroundColor(context.backgroundColor)
rb_regex_name.text = item.name rbRegexName.text = item.name
rb_regex_name.isChecked = item.name == selectedName rbRegexName.isChecked = item.name == selectedName
swt_enabled.isChecked = item.enable swtEnabled.isChecked = item.enable
} else { } else {
rb_regex_name.isChecked = item.name == selectedName rbRegexName.isChecked = item.name == selectedName
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemTocRegexBinding) {
holder.itemView.apply { binding.apply {
rb_regex_name.setOnCheckedChangeListener { buttonView, isChecked -> rbRegexName.setOnCheckedChangeListener { buttonView, isChecked ->
if (buttonView.isPressed && isChecked) { if (buttonView.isPressed && isChecked) {
selectedName = getItem(holder.layoutPosition)?.name selectedName = getItem(holder.layoutPosition)?.name
updateItems(0, itemCount - 1, true) updateItems(0, itemCount - 1, true)
} }
} }
swt_enabled.setOnCheckedChangeListener { buttonView, isChecked -> swtEnabled.setOnCheckedChangeListener { buttonView, isChecked ->
if (buttonView.isPressed) { if (buttonView.isPressed) {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
it.enable = isChecked it.enable = isChecked
@ -226,10 +228,10 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
} }
} }
} }
iv_edit.onClick { ivEdit.onClick {
editRule(getItem(holder.layoutPosition)) editRule(getItem(holder.layoutPosition))
} }
iv_delete.onClick { ivDelete.onClick {
getItem(holder.layoutPosition)?.let { item -> getItem(holder.layoutPosition)?.let { item ->
launch(IO) { launch(IO) {
App.db.txtTocRule().delete(item) App.db.txtTocRule().delete(item)

@ -1,23 +1,27 @@
package io.legado.app.ui.book.search package io.legado.app.ui.book.search
import android.content.Context import android.content.Context
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import kotlinx.android.synthetic.main.item_fillet_text.view.* import io.legado.app.databinding.ItemFilletTextBinding
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class BookAdapter(context: Context, val callBack: CallBack) : class BookAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<Book>(context, R.layout.item_fillet_text) { SimpleRecyclerAdapter<Book, ItemFilletTextBinding>(context) {
override fun convert(holder: ItemViewHolder, item: Book, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
text_view.text = item.name binding: ItemFilletTextBinding,
item: Book,
payloads: MutableList<Any>
) {
with(binding) {
textView.text = item.name
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemFilletTextBinding) {
holder.itemView.apply { holder.itemView.apply {
onClick { onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {

@ -1,12 +1,11 @@
package io.legado.app.ui.book.search package io.legado.app.ui.book.search
import io.legado.app.App import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.SearchKeyword import io.legado.app.data.entities.SearchKeyword
import io.legado.app.databinding.ItemFilletTextBinding
import io.legado.app.ui.widget.anima.explosion_field.ExplosionField import io.legado.app.ui.widget.anima.explosion_field.ExplosionField
import kotlinx.android.synthetic.main.item_fillet_text.view.*
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -15,17 +14,22 @@ import org.jetbrains.anko.sdk27.listeners.onLongClick
class HistoryKeyAdapter(activity: SearchActivity, val callBack: CallBack) : class HistoryKeyAdapter(activity: SearchActivity, val callBack: CallBack) :
SimpleRecyclerAdapter<SearchKeyword>(activity, R.layout.item_fillet_text) { SimpleRecyclerAdapter<SearchKeyword, ItemFilletTextBinding>(activity) {
private val explosionField = ExplosionField.attach2Window(activity) private val explosionField = ExplosionField.attach2Window(activity)
override fun convert(holder: ItemViewHolder, item: SearchKeyword, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
text_view.text = item.word binding: ItemFilletTextBinding,
item: SearchKeyword,
payloads: MutableList<Any>
) {
with(binding) {
textView.text = item.word
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemFilletTextBinding) {
holder.itemView.apply { holder.itemView.apply {
onClick { onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {

@ -2,31 +2,33 @@ package io.legado.app.ui.book.search
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.View
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.ItemSearchBinding
import io.legado.app.utils.gone import io.legado.app.utils.gone
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_bookshelf_list.view.iv_cover
import kotlinx.android.synthetic.main.item_bookshelf_list.view.tv_name
import kotlinx.android.synthetic.main.item_search.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class SearchAdapter(context: Context, val callBack: CallBack) : class SearchAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<SearchBook>(context, R.layout.item_search) { SimpleRecyclerAdapter<SearchBook, ItemSearchBinding>(context) {
override fun convert(holder: ItemViewHolder, item: SearchBook, payloads: MutableList<Any>) { override fun convert(
holder: ItemViewHolder,
binding: ItemSearchBinding,
item: SearchBook,
payloads: MutableList<Any>
) {
val bundle = payloads.getOrNull(0) as? Bundle val bundle = payloads.getOrNull(0) as? Bundle
if (bundle == null) { if (bundle == null) {
bind(holder.itemView, item) bind(binding, item)
} else { } else {
bindChange(holder.itemView, item, bundle) bindChange(binding, item, bundle)
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemSearchBinding) {
holder.itemView.apply { holder.itemView.apply {
onClick { onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
@ -36,45 +38,45 @@ class SearchAdapter(context: Context, val callBack: CallBack) :
} }
} }
private fun bind(itemView: View, searchBook: SearchBook) { private fun bind(binding: ItemSearchBinding, searchBook: SearchBook) {
with(itemView) { with(binding) {
tv_name.text = searchBook.name tvName.text = searchBook.name
tv_author.text = context.getString(R.string.author_show, searchBook.author) tvAuthor.text = context.getString(R.string.author_show, searchBook.author)
bv_originCount.setBadgeCount(searchBook.origins.size) bvOriginCount.setBadgeCount(searchBook.origins.size)
upLasted(itemView, searchBook.latestChapterTitle) upLasted(binding, searchBook.latestChapterTitle)
if (searchBook.intro.isNullOrEmpty()) { if (searchBook.intro.isNullOrEmpty()) {
tv_introduce.text = tvIntroduce.text =
context.getString(R.string.intro_show_null) context.getString(R.string.intro_show_null)
} else { } else {
tv_introduce.text = tvIntroduce.text =
context.getString(R.string.intro_show, searchBook.intro) context.getString(R.string.intro_show, searchBook.intro)
} }
upKind(itemView, searchBook.getKindList()) upKind(binding, searchBook.getKindList())
iv_cover.load(searchBook.coverUrl, searchBook.name, searchBook.author) ivCover.load(searchBook.coverUrl, searchBook.name, searchBook.author)
} }
} }
private fun bindChange(itemView: View, searchBook: SearchBook, bundle: Bundle) { private fun bindChange(binding: ItemSearchBinding, searchBook: SearchBook, bundle: Bundle) {
with(itemView) { with(binding) {
bundle.keySet().map { bundle.keySet().map {
when (it) { when (it) {
"name" -> tv_name.text = searchBook.name "name" -> tvName.text = searchBook.name
"author" -> tv_author.text = "author" -> tvAuthor.text =
context.getString(R.string.author_show, searchBook.author) context.getString(R.string.author_show, searchBook.author)
"origins" -> bv_originCount.setBadgeCount(searchBook.origins.size) "origins" -> bvOriginCount.setBadgeCount(searchBook.origins.size)
"last" -> upLasted(itemView, searchBook.latestChapterTitle) "last" -> upLasted(binding, searchBook.latestChapterTitle)
"intro" -> { "intro" -> {
if (searchBook.intro.isNullOrEmpty()) { if (searchBook.intro.isNullOrEmpty()) {
tv_introduce.text = tvIntroduce.text =
context.getString(R.string.intro_show_null) context.getString(R.string.intro_show_null)
} else { } else {
tv_introduce.text = tvIntroduce.text =
context.getString(R.string.intro_show, searchBook.intro) context.getString(R.string.intro_show, searchBook.intro)
} }
} }
"kind" -> upKind(itemView, searchBook.getKindList()) "kind" -> upKind(binding, searchBook.getKindList())
"cover" -> iv_cover.load( "cover" -> ivCover.load(
searchBook.coverUrl, searchBook.coverUrl,
searchBook.name, searchBook.name,
searchBook.author searchBook.author
@ -84,27 +86,24 @@ class SearchAdapter(context: Context, val callBack: CallBack) :
} }
} }
private fun upLasted(itemView: View, latestChapterTitle: String?) { private fun upLasted(binding: ItemSearchBinding, latestChapterTitle: String?) {
with(itemView) { with(binding) {
if (latestChapterTitle.isNullOrEmpty()) { if (latestChapterTitle.isNullOrEmpty()) {
tv_lasted.gone() tvLasted.gone()
} else { } else {
tv_lasted.text = tvLasted.text =
context.getString( context.getString(R.string.lasted_show, latestChapterTitle)
R.string.lasted_show, tvLasted.visible()
latestChapterTitle
)
tv_lasted.visible()
} }
} }
} }
private fun upKind(itemView: View, kinds: List<String>) = with(itemView) { private fun upKind(binding: ItemSearchBinding, kinds: List<String>) = with(binding) {
if (kinds.isEmpty()) { if (kinds.isEmpty()) {
ll_kind.gone() llKind.gone()
} else { } else {
ll_kind.visible() llKind.visible()
ll_kind.setLabels(kinds) llKind.setLabels(kinds)
} }
} }

@ -4,30 +4,35 @@ import android.content.Context
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.databinding.ItemSearchListBinding
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.utils.getCompatColor import io.legado.app.utils.getCompatColor
import io.legado.app.utils.hexString import io.legado.app.utils.hexString
import kotlinx.android.synthetic.main.item_search_list.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class SearchContentAdapter(context: Context, val callback: Callback) : class SearchContentAdapter(context: Context, val callback: Callback) :
SimpleRecyclerAdapter<SearchResult>(context, R.layout.item_search_list) { SimpleRecyclerAdapter<SearchResult, ItemSearchListBinding>(context) {
val cacheFileNames = hashSetOf<String>() val cacheFileNames = hashSetOf<String>()
val textColor = context.getCompatColor(R.color.primaryText).hexString.substring(2) val textColor = context.getCompatColor(R.color.primaryText).hexString.substring(2)
val accentColor = context.accentColor.hexString.substring(2) val accentColor = context.accentColor.hexString.substring(2)
override fun convert(holder: ItemViewHolder, item: SearchResult, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
binding: ItemSearchListBinding,
item: SearchResult,
payloads: MutableList<Any>
) {
with(binding) {
val isDur = callback.durChapterIndex() == item.chapterIndex val isDur = callback.durChapterIndex() == item.chapterIndex
if (payloads.isEmpty()) { if (payloads.isEmpty()) {
tv_search_result.text = item.getHtmlCompat(textColor, accentColor) tvSearchResult.text = item.getHtmlCompat(textColor, accentColor)
tv_search_result.paint.isFakeBoldText = isDur tvSearchResult.paint.isFakeBoldText = isDur
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemSearchListBinding) {
holder.itemView.onClick { holder.itemView.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callback.openSearchResult(it) callback.openSearchResult(it)

@ -5,29 +5,35 @@ import android.view.View
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import kotlinx.android.synthetic.main.item_log.view.* import io.legado.app.databinding.ItemLogBinding
class BookSourceDebugAdapter(context: Context) : class BookSourceDebugAdapter(context: Context) :
SimpleRecyclerAdapter<String>(context, R.layout.item_log) { SimpleRecyclerAdapter<String, ItemLogBinding>(context) {
override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList<Any>) {
holder.itemView.apply { override fun convert(
if (text_view.getTag(R.id.tag1) == null) { holder: ItemViewHolder,
binding: ItemLogBinding,
item: String,
payloads: MutableList<Any>
) {
binding.apply {
if (textView.getTag(R.id.tag1) == null) {
val listener = object : View.OnAttachStateChangeListener { val listener = object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View) { override fun onViewAttachedToWindow(v: View) {
text_view.isCursorVisible = false textView.isCursorVisible = false
text_view.isCursorVisible = true textView.isCursorVisible = true
} }
override fun onViewDetachedFromWindow(v: View) {} override fun onViewDetachedFromWindow(v: View) {}
} }
text_view.addOnAttachStateChangeListener(listener) textView.addOnAttachStateChangeListener(listener)
text_view.setTag(R.id.tag1, listener) textView.setTag(R.id.tag1, listener)
} }
text_view.text = item textView.text = item
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemLogBinding) {
//nothing //nothing
} }
} }

@ -7,7 +7,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R import io.legado.app.R
import kotlinx.android.synthetic.main.item_source_edit.view.* import io.legado.app.databinding.ItemSourceEditBinding
class BookSourceEditAdapter : RecyclerView.Adapter<BookSourceEditAdapter.MyViewHolder>() { class BookSourceEditAdapter : RecyclerView.Adapter<BookSourceEditAdapter.MyViewHolder>() {
@ -18,9 +18,9 @@ class BookSourceEditAdapter : RecyclerView.Adapter<BookSourceEditAdapter.MyViewH
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context) val binding = ItemSourceEditBinding
.inflate(R.layout.item_source_edit, parent, false) .inflate(LayoutInflater.from(parent.context), parent, false)
return MyViewHolder(view) return MyViewHolder(binding)
} }
override fun onBindViewHolder(holder: MyViewHolder, position: Int) { override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
@ -31,8 +31,9 @@ class BookSourceEditAdapter : RecyclerView.Adapter<BookSourceEditAdapter.MyViewH
return editEntities.size return editEntities.size
} }
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) { class MyViewHolder(val binding: ItemSourceEditBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(editEntity: EditEntity) = with(itemView) {
fun bind(editEntity: EditEntity) = with(binding) {
if (editText.getTag(R.id.tag1) == null) { if (editText.getTag(R.id.tag1) == null) {
val listener = object : View.OnAttachStateChangeListener { val listener = object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View) { override fun onViewAttachedToWindow(v: View) {
@ -55,7 +56,7 @@ class BookSourceEditAdapter : RecyclerView.Adapter<BookSourceEditAdapter.MyViewH
} }
} }
editText.setText(editEntity.value) editText.setText(editEntity.value)
textInputLayout.hint = context.getString(editEntity.hint) textInputLayout.hint = itemView.context.getString(editEntity.hint)
val textWatcher = object : TextWatcher { val textWatcher = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {

@ -12,17 +12,17 @@ import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.databinding.ItemBookSourceBinding
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
import io.legado.app.ui.widget.recycler.ItemTouchCallback.Callback import io.legado.app.ui.widget.recycler.ItemTouchCallback.Callback
import io.legado.app.utils.invisible import io.legado.app.utils.invisible
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_book_source.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.* import java.util.*
class BookSourceAdapter(context: Context, val callBack: CallBack) : class BookSourceAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<BookSource>(context, R.layout.item_book_source), SimpleRecyclerAdapter<BookSource, ItemBookSourceBinding>(context),
Callback { Callback {
private val selected = linkedSetOf<BookSource>() private val selected = linkedSetOf<BookSource>()
@ -57,41 +57,46 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
return selection.sortedBy { it.customOrder } return selection.sortedBy { it.customOrder }
} }
override fun convert(holder: ItemViewHolder, item: BookSource, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
binding: ItemBookSourceBinding,
item: BookSource,
payloads: MutableList<Any>
) {
with(binding) {
val payload = payloads.getOrNull(0) as? Bundle val payload = payloads.getOrNull(0) as? Bundle
if (payload == null) { if (payload == null) {
this.setBackgroundColor(context.backgroundColor) root.setBackgroundColor(context.backgroundColor)
if (item.bookSourceGroup.isNullOrEmpty()) { if (item.bookSourceGroup.isNullOrEmpty()) {
cb_book_source.text = item.bookSourceName cbBookSource.text = item.bookSourceName
} else { } else {
cb_book_source.text = cbBookSource.text =
String.format("%s (%s)", item.bookSourceName, item.bookSourceGroup) String.format("%s (%s)", item.bookSourceName, item.bookSourceGroup)
} }
swt_enabled.isChecked = item.enabled swtEnabled.isChecked = item.enabled
cb_book_source.isChecked = selected.contains(item) cbBookSource.isChecked = selected.contains(item)
upShowExplore(iv_explore, item) upShowExplore(ivExplore, item)
} else { } else {
payload.keySet().map { payload.keySet().map {
when (it) { when (it) {
"selected" -> cb_book_source.isChecked = selected.contains(item) "selected" -> cbBookSource.isChecked = selected.contains(item)
"name", "group" -> if (item.bookSourceGroup.isNullOrEmpty()) { "name", "group" -> if (item.bookSourceGroup.isNullOrEmpty()) {
cb_book_source.text = item.bookSourceName cbBookSource.text = item.bookSourceName
} else { } else {
cb_book_source.text = cbBookSource.text =
String.format("%s (%s)", item.bookSourceName, item.bookSourceGroup) String.format("%s (%s)", item.bookSourceName, item.bookSourceGroup)
} }
"enabled" -> swt_enabled.isChecked = payload.getBoolean(it) "enabled" -> swtEnabled.isChecked = payload.getBoolean(it)
"showExplore" -> upShowExplore(iv_explore, item) "showExplore" -> upShowExplore(ivExplore, item)
} }
} }
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemBookSourceBinding) {
holder.itemView.apply { binding.apply {
swt_enabled.setOnCheckedChangeListener { view, checked -> swtEnabled.setOnCheckedChangeListener { view, checked ->
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
if (view.isPressed) { if (view.isPressed) {
it.enabled = checked it.enabled = checked
@ -99,7 +104,7 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
} }
} }
} }
cb_book_source.setOnCheckedChangeListener { view, checked -> cbBookSource.setOnCheckedChangeListener { view, checked ->
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
if (view.isPressed) { if (view.isPressed) {
if (checked) { if (checked) {
@ -111,13 +116,13 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
} }
} }
} }
iv_edit.onClick { ivEdit.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callBack.edit(it) callBack.edit(it)
} }
} }
iv_menu_more.onClick { ivMenuMore.onClick {
showMenu(iv_menu_more, holder.layoutPosition) showMenu(ivMenuMore, holder.layoutPosition)
} }
} }
} }

@ -7,7 +7,6 @@ import android.view.LayoutInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.EditText
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@ -16,19 +15,21 @@ import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.AppPattern import io.legado.app.constant.AppPattern
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemGroupManageBinding
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.dialog_recycler_view.*
import kotlinx.android.synthetic.main.item_group_manage.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener { class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener {
private lateinit var viewModel: BookSourceViewModel private lateinit var viewModel: BookSourceViewModel
private lateinit var adapter: GroupAdapter private lateinit var adapter: GroupAdapter
private val binding by viewBinding(DialogRecyclerViewBinding::bind)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
@ -48,15 +49,15 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
view.setBackgroundColor(backgroundColor) view.setBackgroundColor(backgroundColor)
tool_bar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
tool_bar.title = getString(R.string.group_manage) binding.toolBar.title = getString(R.string.group_manage)
tool_bar.inflateMenu(R.menu.group_manage) binding.toolBar.inflateMenu(R.menu.group_manage)
tool_bar.menu.applyTint(requireContext()) binding.toolBar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this) binding.toolBar.setOnMenuItemClickListener(this)
adapter = GroupAdapter(requireContext()) adapter = GroupAdapter(requireContext())
recycler_view.layoutManager = LinearLayoutManager(requireContext()) binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(VerticalDivider(requireContext())) binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
initData() initData()
} }
@ -80,16 +81,11 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener {
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun addGroup() { private fun addGroup() {
alert(title = getString(R.string.add_group)) { alert(title = getString(R.string.add_group)) {
var editText: EditText? = null val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
customView { alertBinding.editView.setHint(R.string.group_name)
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { customView = alertBinding.root
editText = edit_view.apply {
setHint(R.string.group_name)
}
}
}
yesButton { yesButton {
editText?.text?.toString()?.let { alertBinding.editView.text?.toString()?.let {
if (it.isNotBlank()) { if (it.isNotBlank()) {
viewModel.addGroup(it) viewModel.addGroup(it)
} }
@ -102,40 +98,39 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener {
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun editGroup(group: String) { private fun editGroup(group: String) {
alert(title = getString(R.string.group_edit)) { alert(title = getString(R.string.group_edit)) {
var editText: EditText? = null val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
customView { alertBinding.editView.setHint(R.string.group_name)
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { customView = alertBinding.root
editText = edit_view.apply {
setHint(R.string.group_name)
setText(group)
}
}
}
yesButton { yesButton {
viewModel.upGroup(group, editText?.text?.toString()) viewModel.upGroup(group, alertBinding.editView.text?.toString())
} }
noButton() noButton()
}.show().requestInputMethod() }.show().requestInputMethod()
} }
private inner class GroupAdapter(context: Context) : private inner class GroupAdapter(context: Context) :
SimpleRecyclerAdapter<String>(context, R.layout.item_group_manage) { SimpleRecyclerAdapter<String, ItemGroupManageBinding>(context) {
override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
setBackgroundColor(context.backgroundColor) binding: ItemGroupManageBinding,
tv_group.text = item item: String,
payloads: MutableList<Any>
) {
with(binding) {
root.setBackgroundColor(context.backgroundColor)
tvGroup.text = item
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemGroupManageBinding) {
holder.itemView.apply { binding.apply {
tv_edit.onClick { tvEdit.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
editGroup(it) editGroup(it)
} }
} }
tv_del.onClick { tvDel.onClick {
getItem(holder.layoutPosition)?.let { viewModel.delGroup(it) } getItem(holder.layoutPosition)?.let { viewModel.delGroup(it) }
} }
} }

@ -1,14 +1,12 @@
package io.legado.app.ui.book.toc package io.legado.app.ui.book.toc
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.paging.PagedListAdapter import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
import io.legado.app.data.entities.Bookmark import io.legado.app.data.entities.Bookmark
import kotlinx.android.synthetic.main.item_bookmark.view.* import io.legado.app.databinding.ItemBookmarkBinding
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onLongClick import org.jetbrains.anko.sdk27.listeners.onLongClick
@ -31,7 +29,9 @@ class BookmarkAdapter(val callback: Callback) : PagedListAdapter<Bookmark, Bookm
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_bookmark, parent, false)) val binding =
ItemBookmarkBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return MyViewHolder(binding)
} }
override fun onBindViewHolder(holder: MyViewHolder, position: Int) { override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
@ -40,11 +40,11 @@ class BookmarkAdapter(val callback: Callback) : PagedListAdapter<Bookmark, Bookm
} }
} }
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) { class MyViewHolder(val binding: ItemBookmarkBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(bookmark: Bookmark, callback: Callback?) = with(itemView) { fun bind(bookmark: Bookmark, callback: Callback?) = with(binding) {
tv_chapter_name.text = bookmark.chapterName tvChapterName.text = bookmark.chapterName
tv_content.text = bookmark.content tvContent.text = bookmark.content
itemView.onClick { itemView.onClick {
callback?.onClick(bookmark) callback?.onClick(bookmark)
} }

@ -5,7 +5,6 @@ import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.widget.EditText
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.paging.LivePagedListBuilder import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList import androidx.paging.PagedList
@ -14,13 +13,14 @@ import io.legado.app.App
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseFragment import io.legado.app.base.VMBaseFragment
import io.legado.app.data.entities.Bookmark import io.legado.app.data.entities.Bookmark
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.FragmentBookmarkBinding
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.getViewModelOfActivity import io.legado.app.utils.getViewModelOfActivity
import io.legado.app.utils.requestInputMethod import io.legado.app.utils.requestInputMethod
import kotlinx.android.synthetic.main.dialog_edit_text.view.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.fragment_bookmark.*
class BookmarkFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragment_bookmark), class BookmarkFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragment_bookmark),
@ -28,7 +28,7 @@ class BookmarkFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragment_
ChapterListViewModel.BookmarkCallBack { ChapterListViewModel.BookmarkCallBack {
override val viewModel: ChapterListViewModel override val viewModel: ChapterListViewModel
get() = getViewModelOfActivity(ChapterListViewModel::class.java) get() = getViewModelOfActivity(ChapterListViewModel::class.java)
private val binding by viewBinding(FragmentBookmarkBinding::bind)
private lateinit var adapter: BookmarkAdapter private lateinit var adapter: BookmarkAdapter
private var bookmarkLiveData: LiveData<PagedList<Bookmark>>? = null private var bookmarkLiveData: LiveData<PagedList<Bookmark>>? = null
@ -39,11 +39,11 @@ class BookmarkFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragment_
} }
private fun initRecyclerView() { private fun initRecyclerView() {
ATH.applyEdgeEffectColor(recycler_view) ATH.applyEdgeEffectColor(binding.recyclerView)
adapter = BookmarkAdapter(this) adapter = BookmarkAdapter(this)
recycler_view.layoutManager = LinearLayoutManager(requireContext()) binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(VerticalDivider(requireContext())) binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
} }
private fun initData() { private fun initData() {
@ -85,18 +85,16 @@ class BookmarkFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragment_
override fun onLongClick(bookmark: Bookmark) { override fun onLongClick(bookmark: Bookmark) {
viewModel.book?.let { book -> viewModel.book?.let { book ->
requireContext().alert(R.string.bookmark) { requireContext().alert(R.string.bookmark) {
var editText: EditText? = null val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
message = book.name + "" + bookmark.chapterName message = book.name + "" + bookmark.chapterName
customView { customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { alertBinding.apply {
editText = edit_view.apply { editView.setHint(R.string.note_content)
setHint(R.string.note_content) editView.setText(bookmark.content)
setText(bookmark.content) }.root
}
}
} }
yesButton { yesButton {
editText?.text?.toString()?.let { editContent -> alertBinding.editView.text?.toString()?.let { editContent ->
bookmark.content = editContent bookmark.content = editContent
App.db.bookmarkDao().update(bookmark) App.db.bookmarkDao().update(bookmark)
} }

@ -1,46 +1,49 @@
package io.legado.app.ui.book.toc package io.legado.app.ui.book.toc
import android.content.Context import android.content.Context
import android.view.View
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.databinding.ItemChapterListBinding
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.utils.getCompatColor import io.legado.app.utils.getCompatColor
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_bookmark.view.tv_chapter_name
import kotlinx.android.synthetic.main.item_chapter_list.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class ChapterListAdapter(context: Context, val callback: Callback) : class ChapterListAdapter(context: Context, val callback: Callback) :
SimpleRecyclerAdapter<BookChapter>(context, R.layout.item_chapter_list) { SimpleRecyclerAdapter<BookChapter, ItemChapterListBinding>(context) {
val cacheFileNames = hashSetOf<String>() val cacheFileNames = hashSetOf<String>()
override fun convert(holder: ItemViewHolder, item: BookChapter, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
binding: ItemChapterListBinding,
item: BookChapter,
payloads: MutableList<Any>
) {
with(binding) {
val isDur = callback.durChapterIndex() == item.index val isDur = callback.durChapterIndex() == item.index
val cached = callback.isLocalBook || cacheFileNames.contains(item.getFileName()) val cached = callback.isLocalBook || cacheFileNames.contains(item.getFileName())
if (payloads.isEmpty()) { if (payloads.isEmpty()) {
if (isDur) { if (isDur) {
tv_chapter_name.setTextColor(context.accentColor) tvChapterName.setTextColor(context.accentColor)
} else { } else {
tv_chapter_name.setTextColor(context.getCompatColor(R.color.primaryText)) tvChapterName.setTextColor(context.getCompatColor(R.color.primaryText))
} }
tv_chapter_name.text = item.title tvChapterName.text = item.title
if (!item.tag.isNullOrEmpty()) { if (!item.tag.isNullOrEmpty()) {
tv_tag.text = item.tag tvTag.text = item.tag
tv_tag.visible() tvTag.visible()
} }
upHasCache(this, isDur, cached) upHasCache(binding, isDur, cached)
} else { } else {
upHasCache(this, isDur, cached) upHasCache(binding, isDur, cached)
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemChapterListBinding) {
holder.itemView.onClick { holder.itemView.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callback.openChapter(it) callback.openChapter(it)
@ -48,15 +51,16 @@ class ChapterListAdapter(context: Context, val callback: Callback) :
} }
} }
private fun upHasCache(itemView: View, isDur: Boolean, cached: Boolean) = itemView.apply { private fun upHasCache(binding: ItemChapterListBinding, isDur: Boolean, cached: Boolean) =
tv_chapter_name.paint.isFakeBoldText = cached binding.apply {
iv_checked.setImageResource(R.drawable.ic_outline_cloud_24) tvChapterName.paint.isFakeBoldText = cached
iv_checked.visible(!cached) ivChecked.setImageResource(R.drawable.ic_outline_cloud_24)
if (isDur) { ivChecked.visible(!cached)
iv_checked.setImageResource(R.drawable.ic_check) if (isDur) {
iv_checked.visible() ivChecked.setImageResource(R.drawable.ic_check)
ivChecked.visible()
}
} }
}
interface Callback { interface Callback {
val isLocalBook: Boolean val isLocalBook: Boolean

@ -12,6 +12,7 @@ import io.legado.app.base.VMBaseFragment
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.databinding.FragmentChapterListBinding
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.bottomBackground
import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.getPrimaryTextColor
@ -20,7 +21,7 @@ import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.ColorUtils import io.legado.app.utils.ColorUtils
import io.legado.app.utils.getViewModelOfActivity import io.legado.app.utils.getViewModelOfActivity
import io.legado.app.utils.observeEvent import io.legado.app.utils.observeEvent
import kotlinx.android.synthetic.main.fragment_chapter_list.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -29,24 +30,24 @@ import org.jetbrains.anko.sdk27.listeners.onClick
class ChapterListFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragment_chapter_list), class ChapterListFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragment_chapter_list),
ChapterListAdapter.Callback, ChapterListAdapter.Callback,
ChapterListViewModel.ChapterListCallBack{ ChapterListViewModel.ChapterListCallBack {
override val viewModel: ChapterListViewModel override val viewModel: ChapterListViewModel
get() = getViewModelOfActivity(ChapterListViewModel::class.java) get() = getViewModelOfActivity(ChapterListViewModel::class.java)
private val binding by viewBinding(FragmentChapterListBinding::bind)
lateinit var adapter: ChapterListAdapter lateinit var adapter: ChapterListAdapter
private var durChapterIndex = 0 private var durChapterIndex = 0
private lateinit var mLayoutManager: UpLinearLayoutManager private lateinit var mLayoutManager: UpLinearLayoutManager
private var tocLiveData: LiveData<List<BookChapter>>? = null private var tocLiveData: LiveData<List<BookChapter>>? = null
private var scrollToDurChapter = false private var scrollToDurChapter = false
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) = with(binding) {
viewModel.chapterCallBack = this viewModel.chapterCallBack = this@ChapterListFragment
val bbg = bottomBackground val bbg = bottomBackground
val btc = requireContext().getPrimaryTextColor(ColorUtils.isColorLight(bbg)) val btc = requireContext().getPrimaryTextColor(ColorUtils.isColorLight(bbg))
ll_chapter_base_info.setBackgroundColor(bbg) llChapterBaseInfo.setBackgroundColor(bbg)
tv_current_chapter_info.setTextColor(btc) tvCurrentChapterInfo.setTextColor(btc)
iv_chapter_top.setColorFilter(btc) ivChapterTop.setColorFilter(btc)
iv_chapter_bottom.setColorFilter(btc) ivChapterBottom.setColorFilter(btc)
initRecyclerView() initRecyclerView()
initView() initView()
initBook() initBook()
@ -55,19 +56,19 @@ class ChapterListFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragme
private fun initRecyclerView() { private fun initRecyclerView() {
adapter = ChapterListAdapter(requireContext(), this) adapter = ChapterListAdapter(requireContext(), this)
mLayoutManager = UpLinearLayoutManager(requireContext()) mLayoutManager = UpLinearLayoutManager(requireContext())
recycler_view.layoutManager = mLayoutManager binding.recyclerView.layoutManager = mLayoutManager
recycler_view.addItemDecoration(VerticalDivider(requireContext())) binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
} }
private fun initView() { private fun initView() = with(binding) {
iv_chapter_top.onClick { mLayoutManager.scrollToPositionWithOffset(0, 0) } ivChapterTop.onClick { mLayoutManager.scrollToPositionWithOffset(0, 0) }
iv_chapter_bottom.onClick { ivChapterBottom.onClick {
if (adapter.itemCount > 0) { if (adapter.itemCount > 0) {
mLayoutManager.scrollToPositionWithOffset(adapter.itemCount - 1, 0) mLayoutManager.scrollToPositionWithOffset(adapter.itemCount - 1, 0)
} }
} }
tv_current_chapter_info.onClick { tvCurrentChapterInfo.onClick {
mLayoutManager.scrollToPositionWithOffset(durChapterIndex, 0) mLayoutManager.scrollToPositionWithOffset(durChapterIndex, 0)
} }
} }
@ -78,7 +79,7 @@ class ChapterListFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragme
initDoc() initDoc()
viewModel.book?.let { viewModel.book?.let {
durChapterIndex = it.durChapterIndex durChapterIndex = it.durChapterIndex
tv_current_chapter_info.text = binding.tvCurrentChapterInfo.text =
"${it.durChapterTitle}(${it.durChapterIndex + 1}/${it.totalChapterNum})" "${it.durChapterTitle}(${it.durChapterIndex + 1}/${it.totalChapterNum})"
initCacheFileNames(it) initCacheFileNames(it)
} }

@ -18,6 +18,7 @@ import io.legado.app.R
import io.legado.app.base.BasePreferenceFragment import io.legado.app.base.BasePreferenceFragment
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.permission.Permissions import io.legado.app.help.permission.Permissions
@ -30,9 +31,7 @@ import io.legado.app.service.WebService
import io.legado.app.ui.main.MainActivity import io.legado.app.ui.main.MainActivity
import io.legado.app.ui.widget.image.CoverImageView import io.legado.app.ui.widget.image.CoverImageView
import io.legado.app.ui.widget.number.NumberPickerDialog import io.legado.app.ui.widget.number.NumberPickerDialog
import io.legado.app.ui.widget.text.AutoCompleteTextView
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.*
import java.io.File import java.io.File
@ -155,15 +154,11 @@ class OtherConfigFragment : BasePreferenceFragment(),
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun showUserAgentDialog() { private fun showUserAgentDialog() {
alert("UserAgent") { alert("UserAgent") {
var editText: AutoCompleteTextView? = null val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
customView { alertBinding.editView.setText(AppConfig.userAgent)
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { customView = alertBinding.root
edit_view.setText(AppConfig.userAgent)
editText = edit_view
}
}
okButton { okButton {
val userAgent = editText?.text?.toString() val userAgent = alertBinding.editView.text?.toString()
if (userAgent.isNullOrBlank()) { if (userAgent.isNullOrBlank()) {
removePref(PreferKey.userAgent) removePref(PreferKey.userAgent)
} else { } else {

@ -15,6 +15,7 @@ import io.legado.app.base.BasePreferenceFragment
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.LauncherIconHelp import io.legado.app.help.LauncherIconHelp
import io.legado.app.help.ThemeConfig import io.legado.app.help.ThemeConfig
@ -23,9 +24,7 @@ import io.legado.app.lib.theme.ATH
import io.legado.app.ui.widget.number.NumberPickerDialog import io.legado.app.ui.widget.number.NumberPickerDialog
import io.legado.app.ui.widget.prefs.ColorPreference import io.legado.app.ui.widget.prefs.ColorPreference
import io.legado.app.ui.widget.prefs.IconListPreference import io.legado.app.ui.widget.prefs.IconListPreference
import io.legado.app.ui.widget.text.AutoCompleteTextView
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.*
@Suppress("SameParameterValue") @Suppress("SameParameterValue")
@ -175,14 +174,10 @@ class ThemeConfigFragment : BasePreferenceFragment(),
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun saveThemeAlert(key: String) { private fun saveThemeAlert(key: String) {
alert(R.string.theme_name) { alert(R.string.theme_name) {
var editText: AutoCompleteTextView? = null val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
customView { customView = alertBinding.root
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view
}
}
okButton { okButton {
editText?.text?.toString()?.let { themeName -> alertBinding.editView.text?.toString()?.let { themeName ->
when (key) { when (key) {
"saveDayTheme" -> { "saveDayTheme" -> {
ThemeConfig.saveDayTheme(requireContext(), themeName) ThemeConfig.saveDayTheme(requireContext(), themeName)

@ -11,18 +11,19 @@ import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemThemeConfigBinding
import io.legado.app.help.ThemeConfig import io.legado.app.help.ThemeConfig
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_recycler_view.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.item_theme_config.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.share import org.jetbrains.anko.share
class ThemeListDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener { class ThemeListDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
private val binding by viewBinding(DialogRecyclerViewBinding::bind)
private lateinit var adapter: Adapter private lateinit var adapter: Adapter
override fun onStart() { override fun onStart() {
@ -40,24 +41,24 @@ class ThemeListDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
} }
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
tool_bar.setTitle(R.string.theme_list) binding.toolBar.setTitle(R.string.theme_list)
initView() initView()
initMenu() initMenu()
initData() initData()
} }
private fun initView() { private fun initView() = with(binding) {
adapter = Adapter() adapter = Adapter()
recycler_view.layoutManager = LinearLayoutManager(requireContext()) recyclerView.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(VerticalDivider(requireContext())) recyclerView.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter recyclerView.adapter = adapter
} }
private fun initMenu() { private fun initMenu() = with(binding) {
tool_bar.setOnMenuItemClickListener(this) toolBar.setOnMenuItemClickListener(this@ThemeListDialog)
tool_bar.inflateMenu(R.menu.theme_list) toolBar.inflateMenu(R.menu.theme_list)
tool_bar.menu.applyTint(requireContext()) toolBar.menu.applyTint(requireContext())
} }
fun initData() { fun initData() {
@ -94,23 +95,29 @@ class ThemeListDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
requireContext().share(json, "主题分享") requireContext().share(json, "主题分享")
} }
inner class Adapter : SimpleRecyclerAdapter<ThemeConfig.Config>(requireContext(), R.layout.item_theme_config) { inner class Adapter :
SimpleRecyclerAdapter<ThemeConfig.Config, ItemThemeConfigBinding>(requireContext()) {
override fun convert(holder: ItemViewHolder, item: ThemeConfig.Config, payloads: MutableList<Any>) {
holder.itemView.apply { override fun convert(
tv_name.text = item.themeName holder: ItemViewHolder,
binding: ItemThemeConfigBinding,
item: ThemeConfig.Config,
payloads: MutableList<Any>
) {
binding.apply {
tvName.text = item.themeName
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemThemeConfigBinding) {
holder.itemView.apply { binding.apply {
onClick { root.onClick {
ThemeConfig.applyConfig(context, ThemeConfig.configList[holder.layoutPosition]) ThemeConfig.applyConfig(context, ThemeConfig.configList[holder.layoutPosition])
} }
iv_share.onClick { ivShare.onClick {
share(holder.layoutPosition) share(holder.layoutPosition)
} }
iv_delete.onClick { ivDelete.onClick {
delete(holder.layoutPosition) delete(holder.layoutPosition)
} }
} }

@ -15,6 +15,9 @@ import io.legado.app.base.VMBaseFragment
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.DialogBookshelfConfigBinding
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.FragmentBookshelfBinding
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
@ -25,13 +28,8 @@ import io.legado.app.ui.book.local.ImportBookActivity
import io.legado.app.ui.book.search.SearchActivity import io.legado.app.ui.book.search.SearchActivity
import io.legado.app.ui.main.MainViewModel import io.legado.app.ui.main.MainViewModel
import io.legado.app.ui.main.bookshelf.books.BooksFragment import io.legado.app.ui.main.bookshelf.books.BooksFragment
import io.legado.app.ui.widget.text.AutoCompleteTextView
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_bookshelf_config.view.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.dialog_edit_text.view.*
import kotlinx.android.synthetic.main.fragment_bookshelf.*
import kotlinx.android.synthetic.main.view_tab_layout.*
import kotlinx.android.synthetic.main.view_title_bar.*
/** /**
* 书架界面 * 书架界面
@ -39,18 +37,20 @@ import kotlinx.android.synthetic.main.view_title_bar.*
class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_bookshelf), class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_bookshelf),
TabLayout.OnTabSelectedListener, TabLayout.OnTabSelectedListener,
SearchView.OnQueryTextListener { SearchView.OnQueryTextListener {
private val binding by viewBinding(FragmentBookshelfBinding::bind)
override val viewModel: BookshelfViewModel override val viewModel: BookshelfViewModel
get() = getViewModel(BookshelfViewModel::class.java) get() = getViewModel(BookshelfViewModel::class.java)
private val activityViewModel: MainViewModel private val activityViewModel: MainViewModel
get() = getViewModelOfActivity(MainViewModel::class.java) get() = getViewModelOfActivity(MainViewModel::class.java)
private lateinit var adapter: FragmentStatePagerAdapter private lateinit var adapter: FragmentStatePagerAdapter
private lateinit var tabLayout: TabLayout
private var bookGroupLiveData: LiveData<List<BookGroup>>? = null private var bookGroupLiveData: LiveData<List<BookGroup>>? = null
private val bookGroups = mutableListOf<BookGroup>() private val bookGroups = mutableListOf<BookGroup>()
private val fragmentMap = hashMapOf<Long, BooksFragment>() private val fragmentMap = hashMapOf<Long, BooksFragment>()
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
setSupportToolbar(toolbar) tabLayout = binding.titleBar.findViewById(R.id.tab_layout)
setSupportToolbar(binding.titleBar.toolbar)
initView() initView()
initBookGroupData() initBookGroupData()
} }
@ -64,7 +64,7 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
when (item.itemId) { when (item.itemId) {
R.id.menu_search -> startActivity<SearchActivity>() R.id.menu_search -> startActivity<SearchActivity>()
R.id.menu_update_toc -> { R.id.menu_update_toc -> {
val group = bookGroups[tab_layout.selectedTabPosition] val group = bookGroups[tabLayout.selectedTabPosition]
val fragment = fragmentMap[group.groupId] val fragment = fragmentMap[group.groupId]
fragment?.getBooks()?.let { fragment?.getBooks()?.let {
activityViewModel.upToc(it) activityViewModel.upToc(it)
@ -87,17 +87,17 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
} }
private val selectedGroup: BookGroup? private val selectedGroup: BookGroup?
get() = bookGroups.getOrNull(view_pager_bookshelf?.currentItem ?: 0) get() = bookGroups.getOrNull(binding.viewPagerBookshelf.currentItem)
private fun initView() { private fun initView() {
ATH.applyEdgeEffectColor(view_pager_bookshelf) ATH.applyEdgeEffectColor(binding.viewPagerBookshelf)
tab_layout.isTabIndicatorFullWidth = false tabLayout.isTabIndicatorFullWidth = false
tab_layout.tabMode = TabLayout.MODE_SCROLLABLE tabLayout.tabMode = TabLayout.MODE_SCROLLABLE
tab_layout.setSelectedTabIndicatorColor(requireContext().accentColor) tabLayout.setSelectedTabIndicatorColor(requireContext().accentColor)
tab_layout.setupWithViewPager(view_pager_bookshelf) tabLayout.setupWithViewPager(binding.viewPagerBookshelf)
view_pager_bookshelf.offscreenPageLimit = 1 binding.viewPagerBookshelf.offscreenPageLimit = 1
adapter = TabFragmentPageAdapter(childFragmentManager) adapter = TabFragmentPageAdapter(childFragmentManager)
view_pager_bookshelf.adapter = adapter binding.viewPagerBookshelf.adapter = adapter
} }
private fun initBookGroupData() { private fun initBookGroupData() {
@ -135,9 +135,9 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
@Synchronized @Synchronized
private fun selectLastTab() { private fun selectLastTab() {
tab_layout.removeOnTabSelectedListener(this) tabLayout.removeOnTabSelectedListener(this)
tab_layout.getTabAt(getPrefInt(PreferKey.saveTabPosition, 0))?.select() tabLayout.getTabAt(getPrefInt(PreferKey.saveTabPosition, 0))?.select()
tab_layout.addOnTabSelectedListener(this) tabLayout.addOnTabSelectedListener(this)
} }
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
@ -145,21 +145,22 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
alert(titleResource = R.string.bookshelf_layout) { alert(titleResource = R.string.bookshelf_layout) {
val bookshelfLayout = getPrefInt(PreferKey.bookshelfLayout) val bookshelfLayout = getPrefInt(PreferKey.bookshelfLayout)
val bookshelfSort = getPrefInt(PreferKey.bookshelfSort) val bookshelfSort = getPrefInt(PreferKey.bookshelfSort)
val root = LayoutInflater.from(requireContext()) val alertBinding =
.inflate(R.layout.dialog_bookshelf_config, null).apply { DialogBookshelfConfigBinding.inflate(LayoutInflater.from(requireContext()))
rg_layout.checkByIndex(bookshelfLayout) .apply {
rg_sort.checkByIndex(bookshelfSort) rgLayout.checkByIndex(bookshelfLayout)
} rgSort.checkByIndex(bookshelfSort)
customView = root }
customView = alertBinding.root
okButton { okButton {
root.apply { alertBinding.apply {
var changed = false var changed = false
if (bookshelfLayout != rg_layout.getCheckedIndex()) { if (bookshelfLayout != rgLayout.getCheckedIndex()) {
putPrefInt(PreferKey.bookshelfLayout, rg_layout.getCheckedIndex()) putPrefInt(PreferKey.bookshelfLayout, rgLayout.getCheckedIndex())
changed = true changed = true
} }
if (bookshelfSort != rg_sort.getCheckedIndex()) { if (bookshelfSort != rgSort.getCheckedIndex()) {
putPrefInt(PreferKey.bookshelfSort, rg_sort.getCheckedIndex()) putPrefInt(PreferKey.bookshelfSort, rgSort.getCheckedIndex())
changed = true changed = true
} }
if (changed) { if (changed) {
@ -174,14 +175,10 @@ class BookshelfFragment : VMBaseFragment<BookshelfViewModel>(R.layout.fragment_b
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun addBookByUrl() { private fun addBookByUrl() {
alert(titleResource = R.string.add_book_url) { alert(titleResource = R.string.add_book_url) {
var editText: AutoCompleteTextView? = null val alertBinding = DialogEditTextBinding.inflate(LayoutInflater.from(requireContext()))
customView { customView = alertBinding.root
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view
}
}
okButton { okButton {
editText?.text?.toString()?.let { alertBinding.editView.text?.toString()?.let {
viewModel.addBookByUrl(it) viewModel.addBookByUrl(it)
} }
} }

@ -2,11 +2,12 @@ package io.legado.app.ui.main.bookshelf.books
import android.content.Context import android.content.Context
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.viewbinding.ViewBinding
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
abstract class BaseBooksAdapter(context: Context, layoutId: Int) : abstract class BaseBooksAdapter<VB : ViewBinding>(context: Context) :
SimpleRecyclerAdapter<Book>(context, layoutId) { SimpleRecyclerAdapter<Book, VB>(context) {
fun notification(bookUrl: String) { fun notification(bookUrl: String) {
for (i in 0 until itemCount) { for (i in 0 until itemCount) {

@ -2,52 +2,59 @@ package io.legado.app.ui.main.bookshelf.books
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.ViewGroup
import io.legado.app.R import androidx.viewbinding.ViewBinding
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.constant.BookType import io.legado.app.constant.BookType
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.databinding.ItemBookshelfGridBinding
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.utils.invisible import io.legado.app.utils.invisible
import kotlinx.android.synthetic.main.item_bookshelf_grid.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onLongClick import org.jetbrains.anko.sdk27.listeners.onLongClick
class BooksAdapterGrid(context: Context, private val callBack: CallBack) : class BooksAdapterGrid(context: Context, private val callBack: CallBack) :
BaseBooksAdapter(context, R.layout.item_bookshelf_grid) { BaseBooksAdapter<ItemBookshelfGridBinding>(context) {
override fun convert(holder: ItemViewHolder, item: Book, payloads: MutableList<Any>) { override fun getViewBinding(parent: ViewGroup, position: Int): ViewBinding {
return ItemBookshelfGridBinding.inflate(inflater, parent, false)
}
override fun convert(
holder: ItemViewHolder,
binding: ItemBookshelfGridBinding,
item: Book,
payloads: MutableList<Any>
) {
val bundle = payloads.getOrNull(0) as? Bundle val bundle = payloads.getOrNull(0) as? Bundle
with(holder.itemView) { if (bundle == null) {
if (bundle == null) { ATH.applyBackgroundTint(binding.root)
ATH.applyBackgroundTint(this) binding.tvName.text = item.name
tv_name.text = item.name binding.ivCover.load(item.getDisplayCover(), item.name, item.author)
iv_cover.load(item.getDisplayCover(), item.name, item.author) upRefresh(binding, item)
upRefresh(this, item) } else {
} else { bundle.keySet().forEach {
bundle.keySet().forEach { when (it) {
when (it) { "name" -> binding.tvName.text = item.name
"name" -> tv_name.text = item.name "cover" -> binding.ivCover.load(item.getDisplayCover(), item.name, item.author)
"cover" -> iv_cover.load(item.getDisplayCover(), item.name, item.author) "refresh" -> upRefresh(binding, item)
"refresh" -> upRefresh(this, item)
}
} }
} }
} }
} }
private fun upRefresh(itemView: View, item: Book) = with(itemView) { private fun upRefresh(binding: ItemBookshelfGridBinding, item: Book) {
if (item.origin != BookType.local && callBack.isUpdate(item.bookUrl)) { if (item.origin != BookType.local && callBack.isUpdate(item.bookUrl)) {
bv_unread.invisible() binding.bvUnread.invisible()
rl_loading.show() binding.rlLoading.show()
} else { } else {
rl_loading.hide() binding.rlLoading.hide()
bv_unread.setBadgeCount(item.getUnreadChapterNum()) binding.bvUnread.setBadgeCount(item.getUnreadChapterNum())
bv_unread.setHighlight(item.lastCheckCount > 0) binding.bvUnread.setHighlight(item.lastCheckCount > 0)
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemBookshelfGridBinding) {
holder.itemView.apply { holder.itemView.apply {
onClick { onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {

@ -2,58 +2,59 @@ package io.legado.app.ui.main.bookshelf.books
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.View
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.constant.BookType import io.legado.app.constant.BookType
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.databinding.ItemBookshelfListBinding
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.utils.invisible import io.legado.app.utils.invisible
import kotlinx.android.synthetic.main.item_bookshelf_list.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onLongClick import org.jetbrains.anko.sdk27.listeners.onLongClick
class BooksAdapterList(context: Context, private val callBack: CallBack) : class BooksAdapterList(context: Context, private val callBack: CallBack) :
BaseBooksAdapter(context, R.layout.item_bookshelf_list) { BaseBooksAdapter<ItemBookshelfListBinding>(context) {
override fun convert(holder: ItemViewHolder, item: Book, payloads: MutableList<Any>) { override fun convert(
holder: ItemViewHolder,
binding: ItemBookshelfListBinding,
item: Book,
payloads: MutableList<Any>
) {
val bundle = payloads.getOrNull(0) as? Bundle val bundle = payloads.getOrNull(0) as? Bundle
with(holder.itemView) { if (bundle == null) {
if (bundle == null) { ATH.applyBackgroundTint(binding.root)
ATH.applyBackgroundTint(this) binding.tvName.text = item.name
tv_name.text = item.name binding.tvAuthor.text = item.author
tv_author.text = item.author binding.tvRead.text = item.durChapterTitle
tv_read.text = item.durChapterTitle binding.tvLast.text = item.latestChapterTitle
tv_last.text = item.latestChapterTitle binding.ivCover.load(item.getDisplayCover(), item.name, item.author)
iv_cover.load(item.getDisplayCover(), item.name, item.author) upRefresh(binding, item)
upRefresh(this, item) } else {
} else { binding.tvRead.text = item.durChapterTitle
tv_read.text = item.durChapterTitle binding.tvLast.text = item.latestChapterTitle
tv_last.text = item.latestChapterTitle bundle.keySet().forEach {
bundle.keySet().forEach { when (it) {
when (it) { "name" -> binding.tvName.text = item.name
"name" -> tv_name.text = item.name "author" -> binding.tvAuthor.text = item.author
"author" -> tv_author.text = item.author "cover" -> binding.ivCover.load(item.getDisplayCover(), item.name, item.author)
"cover" -> iv_cover.load(item.getDisplayCover(), item.name, item.author) "refresh" -> upRefresh(binding, item)
"refresh" -> upRefresh(this, item)
}
} }
} }
} }
} }
private fun upRefresh(itemView: View, item: Book) = with(itemView) { private fun upRefresh(binding: ItemBookshelfListBinding, item: Book) {
if (item.origin != BookType.local && callBack.isUpdate(item.bookUrl)) { if (item.origin != BookType.local && callBack.isUpdate(item.bookUrl)) {
bv_unread.invisible() binding.bvUnread.invisible()
rl_loading.show() binding.rlLoading.show()
} else { } else {
rl_loading.hide() binding.rlLoading.hide()
bv_unread.setHighlight(item.lastCheckCount > 0) binding.bvUnread.setHighlight(item.lastCheckCount > 0)
bv_unread.setBadgeCount(item.getUnreadChapterNum()) binding.bvUnread.setBadgeCount(item.getUnreadChapterNum())
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemBookshelfListBinding) {
holder.itemView.apply { holder.itemView.apply {
onClick { onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {

@ -16,6 +16,7 @@ import io.legado.app.constant.BookType
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.databinding.FragmentBooksBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.IntentDataHelp import io.legado.app.help.IntentDataHelp
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
@ -28,7 +29,7 @@ import io.legado.app.utils.getPrefInt
import io.legado.app.utils.getViewModelOfActivity import io.legado.app.utils.getViewModelOfActivity
import io.legado.app.utils.observeEvent import io.legado.app.utils.observeEvent
import io.legado.app.utils.startActivity import io.legado.app.utils.startActivity
import kotlinx.android.synthetic.main.fragment_books.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlin.math.max import kotlin.math.max
/** /**
@ -48,9 +49,10 @@ class BooksFragment : BaseFragment(R.layout.fragment_books),
} }
} }
private val binding by viewBinding(FragmentBooksBinding::bind)
private val activityViewModel: MainViewModel private val activityViewModel: MainViewModel
get() = getViewModelOfActivity(MainViewModel::class.java) get() = getViewModelOfActivity(MainViewModel::class.java)
private lateinit var booksAdapter: BaseBooksAdapter private lateinit var booksAdapter: BaseBooksAdapter<*>
private var bookshelfLiveData: LiveData<List<Book>>? = null private var bookshelfLiveData: LiveData<List<Book>>? = null
private var position = 0 private var position = 0
private var groupId = -1L private var groupId = -1L
@ -65,35 +67,35 @@ class BooksFragment : BaseFragment(R.layout.fragment_books),
} }
private fun initRecyclerView() { private fun initRecyclerView() {
ATH.applyEdgeEffectColor(rv_bookshelf) ATH.applyEdgeEffectColor(binding.rvBookshelf)
refresh_layout.setColorSchemeColors(accentColor) binding.refreshLayout.setColorSchemeColors(accentColor)
refresh_layout.setOnRefreshListener { binding.refreshLayout.setOnRefreshListener {
refresh_layout.isRefreshing = false binding.refreshLayout.isRefreshing = false
activityViewModel.upToc(booksAdapter.getItems()) activityViewModel.upToc(booksAdapter.getItems())
} }
val bookshelfLayout = getPrefInt(PreferKey.bookshelfLayout) val bookshelfLayout = getPrefInt(PreferKey.bookshelfLayout)
if (bookshelfLayout == 0) { if (bookshelfLayout == 0) {
rv_bookshelf.layoutManager = LinearLayoutManager(context) binding.rvBookshelf.layoutManager = LinearLayoutManager(context)
booksAdapter = BooksAdapterList(requireContext(), this) booksAdapter = BooksAdapterList(requireContext(), this)
} else { } else {
rv_bookshelf.layoutManager = GridLayoutManager(context, bookshelfLayout + 2) binding.rvBookshelf.layoutManager = GridLayoutManager(context, bookshelfLayout + 2)
booksAdapter = BooksAdapterGrid(requireContext(), this) booksAdapter = BooksAdapterGrid(requireContext(), this)
} }
rv_bookshelf.adapter = booksAdapter binding.rvBookshelf.adapter = booksAdapter
booksAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { booksAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
val layoutManager = rv_bookshelf.layoutManager val layoutManager = binding.rvBookshelf.layoutManager
if (positionStart == 0 && layoutManager is LinearLayoutManager) { if (positionStart == 0 && layoutManager is LinearLayoutManager) {
val scrollTo = layoutManager.findFirstVisibleItemPosition() - itemCount val scrollTo = layoutManager.findFirstVisibleItemPosition() - itemCount
rv_bookshelf.scrollToPosition(max(0, scrollTo)) binding.rvBookshelf.scrollToPosition(max(0, scrollTo))
} }
} }
override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) { override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
val layoutManager = rv_bookshelf.layoutManager val layoutManager = binding.rvBookshelf.layoutManager
if (toPosition == 0 && layoutManager is LinearLayoutManager) { if (toPosition == 0 && layoutManager is LinearLayoutManager) {
val scrollTo = layoutManager.findFirstVisibleItemPosition() - itemCount val scrollTo = layoutManager.findFirstVisibleItemPosition() - itemCount
rv_bookshelf.scrollToPosition(max(0, scrollTo)) binding.rvBookshelf.scrollToPosition(max(0, scrollTo))
} }
} }
}) })
@ -109,7 +111,7 @@ class BooksFragment : BaseFragment(R.layout.fragment_books),
else -> App.db.bookDao().observeByGroup(groupId) else -> App.db.bookDao().observeByGroup(groupId)
}.apply { }.apply {
observe(viewLifecycleOwner) { list -> observe(viewLifecycleOwner) { list ->
tv_empty_msg.isGone = list.isNotEmpty() binding.tvEmptyMsg.isGone = list.isNotEmpty()
val books = when (getPrefInt(PreferKey.bookshelfSort)) { val books = when (getPrefInt(PreferKey.bookshelfSort)) {
1 -> list.sortedByDescending { it.latestChapterTime } 1 -> list.sortedByDescending { it.latestChapterTime }
2 -> list.sortedBy { it.name } 2 -> list.sortedBy { it.name }
@ -129,9 +131,9 @@ class BooksFragment : BaseFragment(R.layout.fragment_books),
fun gotoTop() { fun gotoTop() {
if (AppConfig.isEInkMode) { if (AppConfig.isEInkMode) {
rv_bookshelf.scrollToPosition(0) binding.rvBookshelf.scrollToPosition(0)
} else { } else {
rv_bookshelf.smoothScrollToPosition(0) binding.rvBookshelf.smoothScrollToPosition(0)
} }
} }

@ -9,38 +9,43 @@ import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.databinding.ItemFilletTextBinding
import io.legado.app.databinding.ItemFindBookBinding
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.utils.ACache import io.legado.app.utils.ACache
import io.legado.app.utils.dp import io.legado.app.utils.dp
import io.legado.app.utils.gone import io.legado.app.utils.gone
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_fillet_text.view.*
import kotlinx.android.synthetic.main.item_find_book.view.*
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onLongClick import org.jetbrains.anko.sdk27.listeners.onLongClick
class ExploreAdapter(context: Context, private val scope: CoroutineScope, val callBack: CallBack) : class ExploreAdapter(context: Context, private val scope: CoroutineScope, val callBack: CallBack) :
SimpleRecyclerAdapter<BookSource>(context, R.layout.item_find_book) { SimpleRecyclerAdapter<BookSource, ItemFindBookBinding>(context) {
private var exIndex = -1 private var exIndex = -1
private var scrollTo = -1 private var scrollTo = -1
override fun convert(holder: ItemViewHolder, item: BookSource, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
binding: ItemFindBookBinding,
item: BookSource,
payloads: MutableList<Any>
) {
with(binding) {
if (holder.layoutPosition == getActualItemCount() - 1) { if (holder.layoutPosition == getActualItemCount() - 1) {
setPadding(16.dp, 12.dp, 16.dp, 12.dp) root.setPadding(16.dp, 12.dp, 16.dp, 12.dp)
} else { } else {
setPadding(16.dp, 12.dp, 16.dp, 0) root.setPadding(16.dp, 12.dp, 16.dp, 0)
} }
if (payloads.isEmpty()) { if (payloads.isEmpty()) {
tv_name.text = item.bookSourceName tvName.text = item.bookSourceName
} }
if (exIndex == holder.layoutPosition) { if (exIndex == holder.layoutPosition) {
iv_status.setImageResource(R.drawable.ic_arrow_down) ivStatus.setImageResource(R.drawable.ic_arrow_down)
rotate_loading.loadingColor = context.accentColor rotateLoading.loadingColor = context.accentColor
rotate_loading.show() rotateLoading.show()
if (scrollTo >= 0) { if (scrollTo >= 0) {
callBack.scrollTo(scrollTo) callBack.scrollTo(scrollTo)
} }
@ -48,15 +53,18 @@ class ExploreAdapter(context: Context, private val scope: CoroutineScope, val ca
item.getExploreKinds() item.getExploreKinds()
}.onSuccess { kindList -> }.onSuccess { kindList ->
if (!kindList.isNullOrEmpty()) { if (!kindList.isNullOrEmpty()) {
gl_child.visible() glChild.visible()
gl_child.removeAllViews() glChild.removeAllViews()
kindList.map { kind -> kindList.map { kind ->
val tv = LayoutInflater.from(context) val tv = ItemFilletTextBinding.inflate(
.inflate(R.layout.item_fillet_text, gl_child, false) LayoutInflater.from(context),
gl_child.addView(tv) glChild,
tv.text_view.text = kind.title false
)
glChild.addView(tv.root)
tv.textView.text = kind.title
if (!kind.url.isNullOrEmpty()) { if (!kind.url.isNullOrEmpty()) {
tv.text_view.onClick { tv.textView.onClick {
callBack.openExplore( callBack.openExplore(
item.bookSourceUrl, item.bookSourceUrl,
kind.title, kind.title,
@ -67,23 +75,23 @@ class ExploreAdapter(context: Context, private val scope: CoroutineScope, val ca
} }
} }
}.onFinally { }.onFinally {
rotate_loading.hide() rotateLoading.hide()
if (scrollTo >= 0) { if (scrollTo >= 0) {
callBack.scrollTo(scrollTo) callBack.scrollTo(scrollTo)
scrollTo = -1 scrollTo = -1
} }
} }
} else { } else {
iv_status.setImageResource(R.drawable.ic_arrow_right) binding.ivStatus.setImageResource(R.drawable.ic_arrow_right)
rotate_loading.hide() binding.rotateLoading.hide()
gl_child.gone() binding.glChild.gone()
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemFindBookBinding) {
holder.itemView.apply { binding.apply {
ll_title.onClick { llTitle.onClick {
val position = holder.layoutPosition val position = holder.layoutPosition
val oldEx = exIndex val oldEx = exIndex
exIndex = if (exIndex == position) -1 else position exIndex = if (exIndex == position) -1 else position
@ -94,8 +102,8 @@ class ExploreAdapter(context: Context, private val scope: CoroutineScope, val ca
notifyItemChanged(position, false) notifyItemChanged(position, false)
} }
} }
ll_title.onLongClick { llTitle.onLongClick {
showMenu(ll_title, holder.layoutPosition) showMenu(llTitle, holder.layoutPosition)
} }
} }
} }

@ -16,6 +16,7 @@ import io.legado.app.R
import io.legado.app.base.VMBaseFragment import io.legado.app.base.VMBaseFragment
import io.legado.app.constant.AppPattern import io.legado.app.constant.AppPattern
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.databinding.FragmentExploreBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.primaryTextColor import io.legado.app.lib.theme.primaryTextColor
@ -24,9 +25,7 @@ import io.legado.app.ui.book.source.edit.BookSourceEditActivity
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
import io.legado.app.utils.splitNotBlank import io.legado.app.utils.splitNotBlank
import io.legado.app.utils.startActivity import io.legado.app.utils.startActivity
import kotlinx.android.synthetic.main.fragment_explore.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.view_search.*
import kotlinx.android.synthetic.main.view_title_bar.*
import java.text.Collator import java.text.Collator
/** /**
@ -36,16 +35,18 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
ExploreAdapter.CallBack { ExploreAdapter.CallBack {
override val viewModel: ExploreViewModel override val viewModel: ExploreViewModel
get() = getViewModel(ExploreViewModel::class.java) get() = getViewModel(ExploreViewModel::class.java)
private val binding by viewBinding(FragmentExploreBinding::bind)
private lateinit var adapter: ExploreAdapter private lateinit var adapter: ExploreAdapter
private lateinit var linearLayoutManager: LinearLayoutManager private lateinit var linearLayoutManager: LinearLayoutManager
private lateinit var searchView: SearchView
private val groups = linkedSetOf<String>() private val groups = linkedSetOf<String>()
private var liveGroup: LiveData<List<String>>? = null private var liveGroup: LiveData<List<String>>? = null
private var liveExplore: LiveData<List<BookSource>>? = null private var liveExplore: LiveData<List<BookSource>>? = null
private var groupsMenu: SubMenu? = null private var groupsMenu: SubMenu? = null
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
setSupportToolbar(toolbar) searchView = binding.titleBar.findViewById(R.id.search_view)
setSupportToolbar(binding.titleBar.toolbar)
initSearchView() initSearchView()
initRecyclerView() initRecyclerView()
initGroupData() initGroupData()
@ -60,12 +61,12 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
} }
private fun initSearchView() { private fun initSearchView() {
ATH.setTint(search_view, primaryTextColor) ATH.setTint(searchView, primaryTextColor)
search_view.onActionViewExpanded() searchView.onActionViewExpanded()
search_view.isSubmitButtonEnabled = true searchView.isSubmitButtonEnabled = true
search_view.queryHint = getString(R.string.screen_find) searchView.queryHint = getString(R.string.screen_find)
search_view.clearFocus() searchView.clearFocus()
search_view.setOnQueryTextListener(object : SearchView.OnQueryTextListener { searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean { override fun onQueryTextSubmit(query: String?): Boolean {
return false return false
} }
@ -78,17 +79,17 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
} }
private fun initRecyclerView() { private fun initRecyclerView() {
ATH.applyEdgeEffectColor(rv_find) ATH.applyEdgeEffectColor(binding.rvFind)
linearLayoutManager = LinearLayoutManager(context) linearLayoutManager = LinearLayoutManager(context)
rv_find.layoutManager = linearLayoutManager binding.rvFind.layoutManager = linearLayoutManager
adapter = ExploreAdapter(requireContext(), this, this) adapter = ExploreAdapter(requireContext(), this, this)
rv_find.adapter = adapter binding.rvFind.adapter = adapter
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
super.onItemRangeInserted(positionStart, itemCount) super.onItemRangeInserted(positionStart, itemCount)
if (positionStart == 0) { if (positionStart == 0) {
rv_find.scrollToPosition(0) binding.rvFind.scrollToPosition(0)
} }
} }
}) })
@ -114,7 +115,7 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
App.db.bookSourceDao().liveExplore("%$key%") App.db.bookSourceDao().liveExplore("%$key%")
} }
liveExplore?.observe(viewLifecycleOwner, { liveExplore?.observe(viewLifecycleOwner, {
tv_empty_msg.isGone = it.isNotEmpty() || search_view.query.isNotEmpty() binding.tvEmptyMsg.isGone = it.isNotEmpty() || searchView.query.isNotEmpty()
val diffResult = DiffUtil val diffResult = DiffUtil
.calculateDiff(ExploreDiffCallBack(ArrayList(adapter.getItems()), it)) .calculateDiff(ExploreDiffCallBack(ArrayList(adapter.getItems()), it))
adapter.setItems(it) adapter.setItems(it)
@ -135,12 +136,12 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
override fun onCompatOptionsItemSelected(item: MenuItem) { override fun onCompatOptionsItemSelected(item: MenuItem) {
super.onCompatOptionsItemSelected(item) super.onCompatOptionsItemSelected(item)
if (item.groupId == R.id.menu_group_text) { if (item.groupId == R.id.menu_group_text) {
search_view.setQuery(item.title, true) searchView.setQuery(item.title, true)
} }
} }
override fun scrollTo(pos: Int) { override fun scrollTo(pos: Int) {
(rv_find.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(pos, 0) (binding.rvFind.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(pos, 0)
} }
override fun openExplore(sourceUrl: String, title: String, exploreUrl: String) { override fun openExplore(sourceUrl: String, title: String, exploreUrl: String) {
@ -162,9 +163,9 @@ class ExploreFragment : VMBaseFragment<ExploreViewModel>(R.layout.fragment_explo
fun compressExplore() { fun compressExplore() {
if (!adapter.compressExplore()) { if (!adapter.compressExplore()) {
if (AppConfig.isEInkMode) { if (AppConfig.isEInkMode) {
rv_find.scrollToPosition(0) binding.rvFind.scrollToPosition(0)
} else { } else {
rv_find.smoothScrollToPosition(0) binding.rvFind.smoothScrollToPosition(0)
} }
} }
} }

@ -13,6 +13,7 @@ import io.legado.app.base.BaseFragment
import io.legado.app.base.BasePreferenceFragment import io.legado.app.base.BasePreferenceFragment
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.databinding.FragmentMyConfigBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.service.WebService import io.legado.app.service.WebService
@ -30,12 +31,14 @@ import io.legado.app.ui.widget.prefs.NameListPreference
import io.legado.app.ui.widget.prefs.PreferenceCategory import io.legado.app.ui.widget.prefs.PreferenceCategory
import io.legado.app.ui.widget.prefs.SwitchPreference import io.legado.app.ui.widget.prefs.SwitchPreference
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.view_title_bar.* import io.legado.app.utils.viewbindingdelegate.viewBinding
class MyFragment : BaseFragment(R.layout.fragment_my_config), FilePickerDialog.CallBack { class MyFragment : BaseFragment(R.layout.fragment_my_config), FilePickerDialog.CallBack {
private val binding by viewBinding(FragmentMyConfigBinding::bind)
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
setSupportToolbar(toolbar) setSupportToolbar(binding.titleBar.toolbar)
val fragmentTag = "prefFragment" val fragmentTag = "prefFragment"
var preferenceFragment = childFragmentManager.findFragmentByTag(fragmentTag) var preferenceFragment = childFragmentManager.findFragmentByTag(fragmentTag)
if (preferenceFragment == null) preferenceFragment = PreferenceFragment() if (preferenceFragment == null) preferenceFragment = PreferenceFragment()

@ -13,10 +13,15 @@ import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onLongClick import org.jetbrains.anko.sdk27.listeners.onLongClick
class RssAdapter(context: Context, val callBack: CallBack) : class RssAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<RssSource>(context, R.layout.item_rss) { SimpleRecyclerAdapter<RssSource, ItemRssBinding>(context) {
override fun convert(holder: ItemViewHolder, item: RssSource, payloads: MutableList<Any>) { override fun convert(
ItemRssBinding.bind(holder.itemView).apply { holder: ItemViewHolder,
binding: ItemRssBinding,
item: RssSource,
payloads: MutableList<Any>
) {
binding.apply {
tvName.text = item.sourceName tvName.text = item.sourceName
ImageLoader.load(context, item.sourceIcon) ImageLoader.load(context, item.sourceIcon)
.centerCrop() .centerCrop()
@ -26,8 +31,8 @@ class RssAdapter(context: Context, val callBack: CallBack) :
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemRssBinding) {
ItemRssBinding.bind(holder.itemView).apply { binding.apply {
root.onClick { root.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callBack.openRss(it) callBack.openRss(it)

@ -9,6 +9,7 @@ import io.legado.app.App
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseFragment import io.legado.app.base.VMBaseFragment
import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssSource
import io.legado.app.databinding.FragmentRssBinding
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.ui.rss.article.RssSortActivity import io.legado.app.ui.rss.article.RssSortActivity
import io.legado.app.ui.rss.favorites.RssFavoritesActivity import io.legado.app.ui.rss.favorites.RssFavoritesActivity
@ -17,21 +18,20 @@ import io.legado.app.ui.rss.source.manage.RssSourceActivity
import io.legado.app.ui.rss.source.manage.RssSourceViewModel import io.legado.app.ui.rss.source.manage.RssSourceViewModel
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
import io.legado.app.utils.startActivity import io.legado.app.utils.startActivity
import kotlinx.android.synthetic.main.fragment_rss.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.view_title_bar.*
/** /**
* 订阅界面 * 订阅界面
*/ */
class RssFragment : VMBaseFragment<RssSourceViewModel>(R.layout.fragment_rss), class RssFragment : VMBaseFragment<RssSourceViewModel>(R.layout.fragment_rss),
RssAdapter.CallBack { RssAdapter.CallBack {
private val binding by viewBinding(FragmentRssBinding::bind)
private lateinit var adapter: RssAdapter private lateinit var adapter: RssAdapter
override val viewModel: RssSourceViewModel override val viewModel: RssSourceViewModel
get() = getViewModel(RssSourceViewModel::class.java) get() = getViewModel(RssSourceViewModel::class.java)
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
setSupportToolbar(toolbar) setSupportToolbar(binding.titleBar.toolbar)
initRecyclerView() initRecyclerView()
initData() initData()
} }
@ -49,14 +49,14 @@ class RssFragment : VMBaseFragment<RssSourceViewModel>(R.layout.fragment_rss),
} }
private fun initRecyclerView() { private fun initRecyclerView() {
ATH.applyEdgeEffectColor(recycler_view) ATH.applyEdgeEffectColor(binding.recyclerView)
adapter = RssAdapter(requireContext(), this) adapter = RssAdapter(requireContext(), this)
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
} }
private fun initData() { private fun initData() {
App.db.rssSourceDao().liveEnabled().observe(viewLifecycleOwner, { App.db.rssSourceDao().liveEnabled().observe(viewLifecycleOwner, {
tv_empty_msg.isGone = it.isNotEmpty() binding.tvEmptyMsg.isGone = it.isNotEmpty()
adapter.setItems(it) adapter.setItems(it)
}) })
} }

@ -2,53 +2,49 @@ package io.legado.app.ui.widget.recycler
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
import io.legado.app.R import io.legado.app.R
import io.legado.app.databinding.ViewLoadMoreBinding
import io.legado.app.utils.invisible import io.legado.app.utils.invisible
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.view_load_more.view.*
@Suppress("unused") @Suppress("unused")
class LoadMoreView(context: Context, attrs: AttributeSet? = null) : FrameLayout(context, attrs) { class LoadMoreView(context: Context, attrs: AttributeSet? = null) : FrameLayout(context, attrs) {
private val binding = ViewLoadMoreBinding.inflate(LayoutInflater.from(context), this)
var hasMore = true var hasMore = true
private set private set
init {
View.inflate(context, R.layout.view_load_more, this)
}
override fun onAttachedToWindow() { override fun onAttachedToWindow() {
super.onAttachedToWindow() super.onAttachedToWindow()
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
} }
fun startLoad() { fun startLoad() {
tv_text.invisible() binding.tvText.invisible()
rotate_loading.show() binding.rotateLoading.show()
} }
fun stopLoad() { fun stopLoad() {
rotate_loading.hide() binding.rotateLoading.hide()
} }
fun hasMore() { fun hasMore() {
hasMore = true hasMore = true
tv_text.invisible() binding.tvText.invisible()
rotate_loading.show() binding.rotateLoading.show()
} }
fun noMore(msg: String? = null) { fun noMore(msg: String? = null) {
hasMore = false hasMore = false
rotate_loading.hide() binding.rotateLoading.hide()
if (msg != null) { if (msg != null) {
tv_text.text = msg binding.tvText.text = msg
} else { } else {
tv_text.setText(R.string.bottom_line) binding.tvText.setText(R.string.bottom_line)
} }
tv_text.visible() binding.tvText.visible()
} }
} }

@ -1,58 +0,0 @@
@file:Suppress("RedundantVisibilityModifier", "unused")
package io.legado.app.utils.viewbindingdelegate
import android.view.View
import androidx.annotation.IdRes
import androidx.fragment.app.DialogFragment
import androidx.lifecycle.LifecycleOwner
import androidx.viewbinding.ViewBinding
private class DialogFragmentViewBindingProperty<F : DialogFragment, T : ViewBinding>(
viewBinder: (F) -> T
) : ViewBindingProperty<F, T>(viewBinder) {
override fun getLifecycleOwner(thisRef: F): LifecycleOwner {
return if (thisRef.view == null) thisRef.viewLifecycleOwner else thisRef
}
}
/**
* Create new [ViewBinding] associated with the [DialogFragment]
*/
@JvmName("viewBindingDialogFragment")
public fun <F : DialogFragment, T : ViewBinding> DialogFragment.dialogViewBinding(
viewBinder: (F) -> T
): ViewBindingProperty<F, T> {
return DialogFragmentViewBindingProperty(viewBinder)
}
/**
* Create new [ViewBinding] associated with the [DialogFragment]
*
* @param vbFactory Function that create new instance of [ViewBinding]. `MyViewBinding::bind` can be used
*/
@JvmName("viewBindingDialogFragment")
public inline fun <F : DialogFragment, T : ViewBinding> DialogFragment.dialogViewBinding(
crossinline vbFactory: (View) -> T,
crossinline viewProvider: (F) -> View
): ViewBindingProperty<F, T> {
return dialogViewBinding { fragment -> vbFactory(viewProvider(fragment)) }
}
/**
* Create new [ViewBinding] associated with the [DialogFragment][this]
*
* @param vbFactory Function that create new instance of [ViewBinding]. `MyViewBinding::bind` can be used
* @param viewBindingRootId Id of the root view from your custom view
*/
@Suppress("unused")
@JvmName("viewBindingDialogFragment")
public inline fun <T : ViewBinding> DialogFragment.dialogViewBinding(
crossinline vbFactory: (View) -> T,
@IdRes viewBindingRootId: Int
): ViewBindingProperty<DialogFragment, T> {
return viewBinding(vbFactory) { fragment: DialogFragment ->
fragment.dialog!!.window!!.decorView.findViewById(viewBindingRootId)
}
}

@ -2,7 +2,6 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@color/background_menu" android:background="@color/background_menu"

Loading…
Cancel
Save