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.util.SparseArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import java.lang.reflect.ParameterizedType
import java.util.*
/**
@ -16,26 +17,26 @@ import java.util.*
* 通用的adapter 可添加headerfooter以及不同类型item
*/
@Suppress("unused", "MemberVisibilityCanBePrivate")
abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val context: Context) :
RecyclerView.Adapter<ItemViewHolder>() {
constructor(context: Context, vararg delegates: ItemViewDelegate<ITEM>) : this(context) {
constructor(context: Context, vararg delegates: ItemViewDelegate<ITEM, VB>) : this(context) {
addItemViewDelegates(*delegates)
}
constructor(
context: Context,
vararg delegates: Pair<Int, ItemViewDelegate<ITEM>>
vararg delegates: Pair<Int, ItemViewDelegate<ITEM, VB>>
) : this(context) {
addItemViewDelegates(*delegates)
}
private val inflater: LayoutInflater = LayoutInflater.from(context)
val inflater: LayoutInflater = LayoutInflater.from(context)
private var headerItems: SparseArray<View>? = null
private var footerItems: SparseArray<View>? = null
private var headerItems: SparseArray<ViewBinding>? = 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 lock = Object()
@ -58,26 +59,29 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
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
}
fun <DELEGATE : ItemViewDelegate<ITEM>> addItemViewDelegate(delegate: DELEGATE) {
fun addItemViewDelegate(delegate: ItemViewDelegate<ITEM, VB>) {
itemDelegates[itemDelegates.size] = delegate
}
fun <DELEGATE : ItemViewDelegate<ITEM>> addItemViewDelegates(vararg delegates: DELEGATE) {
fun addItemViewDelegates(vararg delegates: ItemViewDelegate<ITEM, VB>) {
delegates.forEach {
addItemViewDelegate(it)
}
}
fun addItemViewDelegates(vararg delegates: Pair<Int, ItemViewDelegate<ITEM>>) =
fun addItemViewDelegates(vararg delegates: Pair<Int, ItemViewDelegate<ITEM, VB>>) =
delegates.forEach {
addItemViewDelegate(it.first, it.second)
}
fun addHeaderView(header: View) {
fun addHeaderView(header: ViewBinding) {
synchronized(lock) {
if (headerItems == null) {
headerItems = SparseArray()
@ -90,7 +94,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
}
}
fun addFooterView(footer: View) =
fun addFooterView(footer: ViewBinding) =
synchronized(lock) {
if (footerItems == null) {
footerItems = SparseArray()
@ -103,7 +107,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
}
fun removeHeaderView(header: View) =
fun removeHeaderView(header: ViewBinding) =
synchronized(lock) {
headerItems?.let {
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) {
footerItems?.let {
val index = it.indexOfValue(footer)
@ -309,16 +313,12 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
}
else -> {
val holder = ItemViewHolder(
inflater.inflate(
itemDelegates.getValue(viewType).layoutId,
parent,
false
)
)
//使用反射得到viewBinding的class
val holder = ItemViewHolder(getViewBinding(parent, viewType))
@Suppress("UNCHECKED_CAST")
itemDelegates.getValue(viewType)
.registerListener(holder)
.registerListener(holder, (holder.binding as VB))
if (itemClickListener != null) {
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) {}
@Suppress("UNCHECKED_CAST")
final override fun onBindViewHolder(
holder: ItemViewHolder,
position: Int,
@ -350,7 +360,7 @@ abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
if (!isHeader(holder.layoutPosition) && !isFooter(holder.layoutPosition)) {
getItem(holder.layoutPosition - getHeaderCount())?.let {
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
import android.content.Context
import androidx.viewbinding.ViewBinding
/**
* Created by Invincible on 2017/11/24.
*
* item代理
*/
abstract class ItemViewDelegate<ITEM>(protected val context: Context, val layoutId: Int) {
abstract class ItemViewDelegate<ITEM, VB : ViewBinding>(protected val context: Context) {
/**
* 如果使用了事件回调,回调里不要直接使用item,会出现不更新的问题,
* 使用getItem(holder.layoutPosition)来获取item,
* 或者使用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
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
/**
* 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
import android.content.Context
import androidx.viewbinding.ViewBinding
/**
* Created by Invincible on 2017/12/15.
*/
abstract class SimpleRecyclerAdapter<ITEM>(context: Context, private val layoutId: Int) :
CommonRecyclerAdapter<ITEM>(context) {
abstract class SimpleRecyclerAdapter<ITEM, VB : ViewBinding>(context: Context) :
CommonRecyclerAdapter<ITEM, VB>(context) {
init {
addItemViewDelegate(object : ItemViewDelegate<ITEM>(context, layoutId) {
addItemViewDelegate(object : ItemViewDelegate<ITEM, VB>(context) {
override fun convert(holder: ItemViewHolder, item: ITEM, payloads: MutableList<Any>) {
this@SimpleRecyclerAdapter.convert(holder, item, payloads)
override fun convert(
holder: ItemViewHolder,
binding: VB,
item: ITEM,
payloads: MutableList<Any>
) {
this@SimpleRecyclerAdapter.convert(holder, binding, item, payloads)
}
override fun registerListener(holder: ItemViewHolder) {
this@SimpleRecyclerAdapter.registerListener(holder)
override fun registerListener(holder: ItemViewHolder, binding: VB) {
this@SimpleRecyclerAdapter.registerListener(holder, binding)
}
})
}
@ -25,10 +31,15 @@ abstract class SimpleRecyclerAdapter<ITEM>(context: Context, private val layoutI
* 如果使用了事件回调,回调里不要直接使用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) :
SimpleRecyclerAdapter<ReadRecordShow>(context, R.layout.item_read_record) {
SimpleRecyclerAdapter<ReadRecordShow, ItemReadRecordBinding>(context) {
override fun convert(
holder: ItemViewHolder,
binding: ItemReadRecordBinding,
item: ReadRecordShow,
payloads: MutableList<Any>
) {
ItemReadRecordBinding.bind(holder.itemView).apply {
binding.apply {
tvBookName.text = item.bookName
tvReadTime.text = formatDuring(item.readTime)
}
}
override fun registerListener(holder: ItemViewHolder) {
ItemReadRecordBinding.bind(holder.itemView).apply {
override fun registerListener(holder: ItemViewHolder, binding: ItemReadRecordBinding) {
binding.apply {
ivRemove.onClick {
alert(R.string.delete, R.string.sure_del) {
okButton {

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

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

@ -4,21 +4,20 @@ import android.content.Context
import android.view.View
import androidx.core.os.bundleOf
import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.ItemArrangeBookBinding
import io.legado.app.lib.theme.backgroundColor
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
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.sdk27.listeners.onClick
import java.util.*
class ArrangeBookAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<Book>(context, R.layout.item_arrange_book),
SimpleRecyclerAdapter<Book, ItemArrangeBookBinding>(context),
ItemTouchCallback.Callback {
val groupRequestCode = 12
private val selectedBooks: HashSet<Book> = hashSetOf()
@ -58,19 +57,24 @@ class ArrangeBookAdapter(context: Context, val callBack: CallBack) :
return books.toTypedArray()
}
override fun convert(holder: ItemViewHolder, item: Book, payloads: MutableList<Any>) {
with(holder.itemView) {
backgroundColor = context.backgroundColor
tv_name.text = item.name
tv_author.text = item.author
tv_author.visibility = if (item.author.isEmpty()) View.GONE else View.VISIBLE
tv_group_s.text = getGroupName(item.group)
override fun convert(
holder: ItemViewHolder,
binding: ItemArrangeBookBinding,
item: Book,
payloads: MutableList<Any>
) {
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)
}
}
override fun registerListener(holder: ItemViewHolder) {
holder.itemView.apply {
override fun registerListener(holder: ItemViewHolder, binding: ItemArrangeBookBinding) {
binding.apply {
checkbox.setOnCheckedChangeListener { buttonView, isChecked ->
getItem(holder.layoutPosition)?.let {
if (buttonView.isPressed) {
@ -84,7 +88,7 @@ class ArrangeBookAdapter(context: Context, val callBack: CallBack) :
}
}
onClick {
root.onClick {
getItem(holder.layoutPosition)?.let {
checkbox.isChecked = !checkbox.isChecked
if (checkbox.isChecked) {
@ -95,12 +99,12 @@ class ArrangeBookAdapter(context: Context, val callBack: CallBack) :
callBack.upSelectCount()
}
}
tv_delete.onClick {
tvDelete.onClick {
getItem(holder.layoutPosition)?.let {
callBack.deleteBook(it)
}
}
tv_group.onClick {
tvGroup.onClick {
getItem(holder.layoutPosition)?.let {
actionItem = it
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.data.entities.Book
import io.legado.app.data.entities.BookChapter
import io.legado.app.databinding.ItemDownloadBinding
import io.legado.app.service.help.CacheBook
import kotlinx.android.synthetic.main.item_download.view.*
import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArraySet
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>>()
var downloadMap: ConcurrentHashMap<String, CopyOnWriteArraySet<BookChapter>>? = null
override fun convert(holder: ItemViewHolder, item: Book, payloads: MutableList<Any>) {
with(holder.itemView) {
override fun convert(
holder: ItemViewHolder,
binding: ItemDownloadBinding,
item: Book,
payloads: MutableList<Any>
) {
with(binding) {
if (payloads.isEmpty()) {
tv_name.text = item.name
tv_author.text = context.getString(R.string.author_show, item.getRealAuthor())
tvName.text = item.name
tvAuthor.text = context.getString(R.string.author_show, item.getRealAuthor())
val cs = cacheChapters[item.bookUrl]
if (cs == null) {
tv_download.setText(R.string.loading)
tvDownload.setText(R.string.loading)
} else {
tv_download.text =
tvDownload.text =
context.getString(R.string.download_count, cs.size, item.totalChapterNum)
}
upDownloadIv(iv_download, item)
upDownloadIv(ivDownload, item)
} else {
val cacheSize = cacheChapters[item.bookUrl]?.size ?: 0
tv_download.text =
tvDownload.text =
context.getString(R.string.download_count, cacheSize, item.totalChapterNum)
upDownloadIv(iv_download, item)
upDownloadIv(ivDownload, item)
}
}
}
override fun registerListener(holder: ItemViewHolder) {
holder.itemView.apply {
iv_download.onClick {
override fun registerListener(holder: ItemViewHolder, binding: ItemDownloadBinding) {
with(binding) {
ivDownload.onClick {
getItem(holder.layoutPosition)?.let {
if (downloadMap?.containsKey(it.bookUrl) == true) {
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)
}
}

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

@ -1,7 +1,6 @@
package io.legado.app.ui.book.changecover
import android.content.Context
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.SearchBook
@ -9,16 +8,21 @@ import io.legado.app.databinding.ItemCoverBinding
import org.jetbrains.anko.sdk27.listeners.onClick
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>) {
ItemCoverBinding.bind(holder.itemView).apply {
override fun convert(
holder: ItemViewHolder,
binding: ItemCoverBinding,
item: SearchBook,
payloads: MutableList<Any>
) {
binding.apply {
ivCover.load(item.coverUrl, item.name, item.author)
tvSource.text = item.originName
}
}
override fun registerListener(holder: ItemViewHolder) {
override fun registerListener(holder: ItemViewHolder, binding: ItemCoverBinding) {
holder.itemView.apply {
onClick {
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.SimpleRecyclerAdapter
import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.ItemChangeSourceBinding
import io.legado.app.utils.invisible
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.onLongClick
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
holder.itemView.apply {
binding.apply {
if (bundle == null) {
tv_origin.text = item.originName
tv_last.text = item.getDisplayLastChapterTitle()
tvOrigin.text = item.originName
tvLast.text = item.getDisplayLastChapterTitle()
if (callBack.bookUrl == item.bookUrl) {
iv_checked.visible()
ivChecked.visible()
} else {
iv_checked.invisible()
ivChecked.invisible()
}
} else {
bundle.keySet().map {
when (it) {
"name" -> tv_origin.text = item.originName
"latest" -> tv_last.text = item.getDisplayLastChapterTitle()
"name" -> tvOrigin.text = item.originName
"latest" -> tvLast.text = item.getDisplayLastChapterTitle()
}
}
}
}
}
override fun registerListener(holder: ItemViewHolder) {
override fun registerListener(holder: ItemViewHolder, binding: ItemChangeSourceBinding) {
holder.itemView.onClick {
getItem(holder.layoutPosition)?.let {
callBack.changeTo(it)

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

@ -6,43 +6,46 @@ import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.ItemSearchBinding
import io.legado.app.utils.gone
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
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>) {
holder.itemView.apply {
tv_name.text = item.name
tv_author.text = context.getString(R.string.author_show, item.author)
override fun convert(
holder: ItemViewHolder,
binding: ItemSearchBinding,
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()) {
tv_lasted.gone()
tvLasted.gone()
} else {
tv_lasted.text = context.getString(R.string.lasted_show, item.latestChapterTitle)
tv_lasted.visible()
tvLasted.text = context.getString(R.string.lasted_show, item.latestChapterTitle)
tvLasted.visible()
}
if (item.intro.isNullOrEmpty()) {
tv_introduce.text = context.getString(R.string.intro_show_null)
tvIntroduce.text = context.getString(R.string.intro_show_null)
} 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()
if (kinds.isEmpty()) {
ll_kind.gone()
llKind.gone()
} else {
ll_kind.visible()
ll_kind.setLabels(kinds)
llKind.visible()
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 {
getItem(holder.layoutPosition)?.let {
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.SimpleRecyclerAdapter
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.backgroundColor
import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.*
import kotlinx.android.synthetic.main.dialog_recycler_view.*
import kotlinx.android.synthetic.main.item_group_manage.view.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.*
import kotlin.collections.ArrayList
@ -37,6 +37,7 @@ import kotlin.collections.ArrayList
class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
private lateinit var viewModel: GroupViewModel
private lateinit var adapter: GroupAdapter
private val binding by viewBinding(DialogRecyclerViewBinding::bind)
override fun onStart() {
super.onStart()
@ -54,8 +55,8 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
}
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setBackgroundColor(primaryColor)
tool_bar.title = getString(R.string.group_manage)
binding.toolBar.setBackgroundColor(primaryColor)
binding.toolBar.title = getString(R.string.group_manage)
initView()
initData()
initMenu()
@ -63,15 +64,15 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun initView() {
adapter = GroupAdapter(requireContext())
recycler_view.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
binding.recyclerView.adapter = adapter
val itemTouchCallback = ItemTouchCallback(adapter)
itemTouchCallback.isCanDrag = true
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(recycler_view)
tv_ok.setTextColor(requireContext().accentColor)
tv_ok.visible()
tv_ok.onClick { dismiss() }
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(binding.recyclerView)
binding.tvOk.setTextColor(requireContext().accentColor)
binding.tvOk.visible()
binding.tvOk.onClick { dismiss() }
}
private fun initData() {
@ -83,9 +84,9 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
}
private fun initMenu() {
tool_bar.setOnMenuItemClickListener(this)
tool_bar.inflateMenu(R.menu.book_group_manage)
tool_bar.menu.applyTint(requireContext())
binding.toolBar.setOnMenuItemClickListener(this)
binding.toolBar.inflateMenu(R.menu.book_group_manage)
binding.toolBar.menu.applyTint(requireContext())
}
override fun onMenuItemClick(item: MenuItem?): Boolean {
@ -101,9 +102,8 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
var editText: EditText? = null
customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view.apply {
setHint(R.string.group_name)
}
editText = findViewById(R.id.edit_view)
editText?.setHint(R.string.group_name)
}
}
yesButton {
@ -123,10 +123,9 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
var editText: EditText? = null
customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view.apply {
setHint(R.string.group_name)
setText(bookGroup.groupName)
}
editText = findViewById(R.id.edit_view)
editText!!.setHint(R.string.group_name)
editText!!.setText(bookGroup.groupName)
}
}
yesButton {
@ -174,26 +173,31 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
}
private inner class GroupAdapter(context: Context) :
SimpleRecyclerAdapter<BookGroup>(context, R.layout.item_group_manage),
SimpleRecyclerAdapter<BookGroup, ItemGroupManageBinding>(context),
ItemTouchCallback.Callback {
private var isMoved = false
override fun convert(holder: ItemViewHolder, item: BookGroup, payloads: MutableList<Any>) {
holder.itemView.apply {
setBackgroundColor(context.backgroundColor)
tv_group.text = item.getManageName(context)
sw_show.isChecked = item.show
tv_del.isGone = item.groupId < 0
sw_show.isGone = item.groupId >= 0
override fun convert(
holder: ItemViewHolder,
binding: ItemGroupManageBinding,
item: BookGroup,
payloads: MutableList<Any>
) {
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) {
holder.itemView.apply {
tv_edit.onClick { getItem(holder.layoutPosition)?.let { editGroup(it) } }
tv_del.onClick { getItem(holder.layoutPosition)?.let { deleteGroup(it) } }
sw_show.setOnCheckedChangeListener { buttonView, isChecked ->
override fun registerListener(holder: ItemViewHolder, binding: ItemGroupManageBinding) {
with(binding) {
tvEdit.onClick { getItem(holder.layoutPosition)?.let { editGroup(it) } }
tvDel.onClick { getItem(holder.layoutPosition)?.let { deleteGroup(it) } }
swShow.setOnCheckedChangeListener { buttonView, isChecked ->
if (buttonView.isPressed) {
getItem(holder.layoutPosition)?.let {
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.SimpleRecyclerAdapter
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.theme.accentColor
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.getViewModel
import io.legado.app.utils.requestInputMethod
import kotlinx.android.synthetic.main.dialog_book_group_picker.*
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 io.legado.app.utils.viewbindingdelegate.viewBinding
import org.jetbrains.anko.sdk27.listeners.onClick
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 lateinit var viewModel: GroupViewModel
private lateinit var adapter: GroupAdapter
@ -74,7 +74,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
}
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setBackgroundColor(primaryColor)
binding.toolBar.setBackgroundColor(primaryColor)
callBack = activity as? CallBack
arguments?.let {
groupId = it.getLong("groupId")
@ -85,20 +85,20 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
}
private fun initView() {
tool_bar.title = getString(R.string.group_select)
tool_bar.inflateMenu(R.menu.book_group_manage)
tool_bar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this)
binding.toolBar.title = getString(R.string.group_select)
binding.toolBar.inflateMenu(R.menu.book_group_manage)
binding.toolBar.menu.applyTint(requireContext())
binding.toolBar.setOnMenuItemClickListener(this)
adapter = GroupAdapter(requireContext())
recycler_view.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
binding.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
binding.recyclerView.adapter = adapter
val itemTouchCallback = ItemTouchCallback(adapter)
itemTouchCallback.isCanDrag = true
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(recycler_view)
tv_cancel.onClick { dismiss() }
tv_ok.setTextColor(requireContext().accentColor)
tv_ok.onClick {
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(binding.recyclerView)
binding.tvCancel.onClick { dismiss() }
binding.tvOk.setTextColor(requireContext().accentColor)
binding.tvOk.onClick {
callBack?.upGroup(requestCode, groupId)
dismiss()
}
@ -123,9 +123,8 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
var editText: EditText? = null
customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view.apply {
setHint(R.string.group_name)
}
editText = findViewById(R.id.edit_view)
editText!!.setHint(R.string.group_name)
}
}
yesButton {
@ -145,10 +144,9 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
var editText: EditText? = null
customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = edit_view.apply {
setHint(R.string.group_name)
setText(bookGroup.groupName)
}
editText = findViewById(R.id.edit_view)
editText!!.setHint(R.string.group_name)
editText!!.setText(bookGroup.groupName)
}
}
yesButton {
@ -159,22 +157,27 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
}
private inner class GroupAdapter(context: Context) :
SimpleRecyclerAdapter<BookGroup>(context, R.layout.item_group_select),
SimpleRecyclerAdapter<BookGroup, ItemGroupSelectBinding>(context),
ItemTouchCallback.Callback {
private var isMoved: Boolean = false
override fun convert(holder: ItemViewHolder, item: BookGroup, payloads: MutableList<Any>) {
holder.itemView.apply {
setBackgroundColor(context.backgroundColor)
cb_group.text = item.groupName
cb_group.isChecked = (groupId and item.groupId) > 0
override fun convert(
holder: ItemViewHolder,
binding: ItemGroupSelectBinding,
item: BookGroup,
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) {
holder.itemView.apply {
cb_group.setOnCheckedChangeListener { buttonView, isChecked ->
override fun registerListener(holder: ItemViewHolder, binding: ItemGroupSelectBinding) {
with(binding) {
cbGroup.setOnCheckedChangeListener { buttonView, isChecked ->
getItem(holder.layoutPosition)?.let {
if (buttonView.isPressed) {
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.SimpleRecyclerAdapter
import io.legado.app.data.entities.BookChapter
import io.legado.app.databinding.ItemChapterListBinding
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.textColorResource
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>) {
holder.itemView.apply {
tv_chapter_name.text = item.title
override fun convert(
holder: ItemViewHolder,
binding: ItemChapterListBinding,
item: BookChapter,
payloads: MutableList<Any>
) {
with(binding) {
tvChapterName.text = item.title
if (item.index == callBack.durChapterIndex()) {
tv_chapter_name.setTextColor(context.accentColor)
tvChapterName.setTextColor(context.accentColor)
} 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 {
this.onClick {
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.SimpleRecyclerAdapter
import io.legado.app.constant.AppConst
import io.legado.app.databinding.ItemImportBookBinding
import io.legado.app.utils.*
import kotlinx.android.synthetic.main.item_import_book.view.*
import org.jetbrains.anko.sdk27.listeners.onClick
class ImportBookAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<DocItem>(context, R.layout.item_import_book) {
SimpleRecyclerAdapter<DocItem, ItemImportBookBinding>(context) {
var selectedUris = hashSetOf<String>()
var checkableCount = 0
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>) {
holder.itemView.apply {
override fun convert(
holder: ItemViewHolder,
binding: ItemImportBookBinding,
item: DocItem,
payloads: MutableList<Any>
) {
with(binding) {
if (payloads.isEmpty()) {
if (item.isDir) {
iv_icon.setImageResource(R.drawable.ic_folder)
iv_icon.visible()
cb_select.invisible()
ll_brief.gone()
cb_select.isChecked = false
ivIcon.setImageResource(R.drawable.ic_folder)
ivIcon.visible()
cbSelect.invisible()
llBrief.gone()
cbSelect.isChecked = false
} else {
if (bookFileNames.contains(item.name)) {
iv_icon.setImageResource(R.drawable.ic_book_has)
iv_icon.visible()
cb_select.invisible()
ivIcon.setImageResource(R.drawable.ic_book_has)
ivIcon.visible()
cbSelect.invisible()
} else {
iv_icon.invisible()
cb_select.visible()
ivIcon.invisible()
cbSelect.visible()
}
ll_brief.visible()
tv_tag.text = item.name.substringAfterLast(".")
tv_size.text = StringUtils.toSize(item.size)
tv_date.text = AppConst.dateFormat.format(item.date)
cb_select.isChecked = selectedUris.contains(item.uri.toString())
llBrief.visible()
tvTag.text = item.name.substringAfterLast(".")
tvSize.text = StringUtils.toSize(item.size)
tvDate.text = AppConst.dateFormat.format(item.date)
cbSelect.isChecked = selectedUris.contains(item.uri.toString())
}
tv_name.text = item.name
tvName.text = item.name
} 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 {
getItem(holder.layoutPosition)?.let {
if (it.isDir) {

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

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

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

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

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

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

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

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

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

@ -17,17 +17,23 @@ import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.PreferKey
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.theme.primaryColor
import io.legado.app.service.help.ReadAloud
import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_http_tts_edit.view.*
import kotlinx.android.synthetic.main.dialog_recycler_view.*
import kotlinx.android.synthetic.main.item_http_tts.view.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
import org.jetbrains.anko.sdk27.listeners.onClick
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() {
super.onStart()
@ -35,11 +41,6 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
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(
inflater: LayoutInflater,
container: ViewGroup?,
@ -55,33 +56,33 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
initData()
}
private fun initView() {
tool_bar.setBackgroundColor(primaryColor)
tool_bar.setTitle(R.string.speak_engine)
recycler_view.layoutManager = LinearLayoutManager(requireContext())
private fun initView() = with(binding) {
toolBar.setBackgroundColor(primaryColor)
toolBar.setTitle(R.string.speak_engine)
recyclerView.layoutManager = LinearLayoutManager(requireContext())
adapter = Adapter(requireContext())
recycler_view.adapter = adapter
tv_footer_left.setText(R.string.local_tts)
tv_footer_left.visible()
tv_footer_left.onClick {
recyclerView.adapter = adapter
tvFooterLeft.setText(R.string.local_tts)
tvFooterLeft.visible()
tvFooterLeft.onClick {
removePref(PreferKey.speakEngine)
dismiss()
}
tv_ok.visible()
tv_ok.onClick {
tvOk.visible()
tvOk.onClick {
putPrefLong(PreferKey.speakEngine, engineId)
dismiss()
}
tv_cancel.visible()
tv_cancel.onClick {
tvCancel.visible()
tvCancel.onClick {
dismiss()
}
}
private fun initMenu() {
tool_bar.inflateMenu(R.menu.speak_engine)
tool_bar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this)
private fun initMenu() = with(binding) {
toolBar.inflateMenu(R.menu.speak_engine)
toolBar.menu.applyTint(requireContext())
toolBar.setOnMenuItemClickListener(this@SpeakEngineDialog)
}
private fun initData() {
@ -104,20 +105,16 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun editHttpTTS(v: HttpTTS? = null) {
val httpTTS = v?.copy() ?: HttpTTS()
requireContext().alert(titleResource = R.string.speak_engine) {
var rootView: View? = null
customView {
LayoutInflater.from(requireContext())
.inflate(R.layout.dialog_http_tts_edit, null).apply {
rootView = this
tv_name.setText(httpTTS.name)
tv_url.setText(httpTTS.url)
}
}
val alertBinding =
DialogHttpTtsEditBinding.inflate(LayoutInflater.from(requireContext()))
alertBinding.tvName.setText(httpTTS.name)
alertBinding.tvUrl.setText(httpTTS.url)
customView = alertBinding.root
cancelButton()
okButton {
rootView?.apply {
httpTTS.name = tv_name.text.toString()
httpTTS.url = tv_url.text.toString()
alertBinding.apply {
httpTTS.name = tvName.text.toString()
httpTTS.url = tvUrl.text.toString()
App.db.httpTTSDao().insert(httpTTS)
ReadAloud.upReadAloudClass()
}
@ -132,27 +129,32 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
}
inner class Adapter(context: Context) :
SimpleRecyclerAdapter<HttpTTS>(context, R.layout.item_http_tts) {
override fun convert(holder: ItemViewHolder, item: HttpTTS, payloads: MutableList<Any>) {
holder.itemView.apply {
cb_name.text = item.name
cb_name.isChecked = item.id == engineId
SimpleRecyclerAdapter<HttpTTS, ItemHttpTtsBinding>(context) {
override fun convert(
holder: ItemViewHolder,
binding: ItemHttpTtsBinding,
item: HttpTTS,
payloads: MutableList<Any>
) {
binding.apply {
cbName.text = item.name
cbName.isChecked = item.id == engineId
}
}
override fun registerListener(holder: ItemViewHolder) {
holder.itemView.apply {
cb_name.onClick {
override fun registerListener(holder: ItemViewHolder, binding: ItemHttpTtsBinding) {
binding.apply {
cbName.onClick {
getItem(holder.layoutPosition)?.let { httpTTS ->
engineId = httpTTS.id
notifyItemRangeChanged(0, getActualItemCount())
}
}
iv_edit.onClick {
ivEdit.onClick {
editHttpTTS(getItem(holder.layoutPosition))
}
iv_menu_delete.onClick {
ivMenuDelete.onClick {
getItem(holder.layoutPosition)?.let { 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.base.BaseDialogFragment
import io.legado.app.constant.EventBus
import io.legado.app.databinding.DialogTipConfigBinding
import io.legado.app.help.ReadBookConfig
import io.legado.app.help.ReadTipConfig
import io.legado.app.lib.dialogs.selector
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.onClick
@ -22,6 +23,8 @@ class TipConfigDialog : BaseDialogFragment() {
const val TIP_COLOR = 7897
}
private val binding by viewBinding(DialogTipConfigBinding::bind)
override fun onStart() {
super.onStart()
dialog?.window
@ -44,27 +47,27 @@ class TipConfigDialog : BaseDialogFragment() {
}
}
private fun initView() {
rg_title_mode.checkByIndex(ReadBookConfig.titleMode)
dsb_title_size.progress = ReadBookConfig.titleSize
dsb_title_top.progress = ReadBookConfig.titleTopSpacing
dsb_title_bottom.progress = ReadBookConfig.titleBottomSpacing
private fun initView() = with(binding) {
rgTitleMode.checkByIndex(ReadBookConfig.titleMode)
dsbTitleSize.progress = ReadBookConfig.titleSize
dsbTitleTop.progress = ReadBookConfig.titleTopSpacing
dsbTitleBottom.progress = ReadBookConfig.titleBottomSpacing
tv_header_show.text = ReadTipConfig.headerModes[ReadTipConfig.headerMode]
tv_footer_show.text = ReadTipConfig.footerModes[ReadTipConfig.footerMode]
tvHeaderShow.text = ReadTipConfig.headerModes[ReadTipConfig.headerMode]
tvFooterShow.text = ReadTipConfig.footerModes[ReadTipConfig.footerMode]
tv_header_left.text = ReadTipConfig.tipHeaderLeftStr
tv_header_middle.text = ReadTipConfig.tipHeaderMiddleStr
tv_header_right.text = ReadTipConfig.tipHeaderRightStr
tv_footer_left.text = ReadTipConfig.tipFooterLeftStr
tv_footer_middle.text = ReadTipConfig.tipFooterMiddleStr
tv_footer_right.text = ReadTipConfig.tipFooterRightStr
tvHeaderLeft.text = ReadTipConfig.tipHeaderLeftStr
tvHeaderMiddle.text = ReadTipConfig.tipHeaderMiddleStr
tvHeaderRight.text = ReadTipConfig.tipHeaderRightStr
tvFooterLeft.text = ReadTipConfig.tipFooterLeftStr
tvFooterMiddle.text = ReadTipConfig.tipFooterMiddleStr
tvFooterRight.text = ReadTipConfig.tipFooterRightStr
upTvTipColor()
}
private fun upTvTipColor() {
tv_tip_color.text =
binding.tvTipColor.text =
if (ReadTipConfig.tipColor == 0) {
"跟随正文"
} else {
@ -72,86 +75,86 @@ class TipConfigDialog : BaseDialogFragment() {
}
}
private fun initEvent() {
rg_title_mode.onCheckedChange { _, checkedId ->
ReadBookConfig.titleMode = rg_title_mode.getIndexById(checkedId)
private fun initEvent() = with(binding) {
rgTitleMode.onCheckedChange { _, checkedId ->
ReadBookConfig.titleMode = rgTitleMode.getIndexById(checkedId)
postEvent(EventBus.UP_CONFIG, true)
}
dsb_title_size.onChanged = {
dsbTitleSize.onChanged = {
ReadBookConfig.titleSize = it
postEvent(EventBus.UP_CONFIG, true)
}
dsb_title_top.onChanged = {
dsbTitleTop.onChanged = {
ReadBookConfig.titleTopSpacing = it
postEvent(EventBus.UP_CONFIG, true)
}
dsb_title_bottom.onChanged = {
dsbTitleBottom.onChanged = {
ReadBookConfig.titleBottomSpacing = it
postEvent(EventBus.UP_CONFIG, true)
}
ll_header_show.onClick {
llHeaderShow.onClick {
selector(items = ReadTipConfig.headerModes.values.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)
}
}
ll_footer_show.onClick {
llFooterShow.onClick {
selector(items = ReadTipConfig.footerModes.values.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)
}
}
ll_header_left.onClick {
llHeaderLeft.onClick {
selector(items = ReadTipConfig.tips) { _, i ->
clearRepeat(i)
ReadTipConfig.tipHeaderLeft = i
tv_header_left.text = ReadTipConfig.tips[i]
tvHeaderLeft.text = ReadTipConfig.tips[i]
postEvent(EventBus.UP_CONFIG, true)
}
}
ll_header_middle.onClick {
llHeaderMiddle.onClick {
selector(items = ReadTipConfig.tips) { _, i ->
clearRepeat(i)
ReadTipConfig.tipHeaderMiddle = i
tv_header_middle.text = ReadTipConfig.tips[i]
tvHeaderMiddle.text = ReadTipConfig.tips[i]
postEvent(EventBus.UP_CONFIG, true)
}
}
ll_header_right.onClick {
llHeaderRight.onClick {
selector(items = ReadTipConfig.tips) { _, i ->
clearRepeat(i)
ReadTipConfig.tipHeaderRight = i
tv_header_right.text = ReadTipConfig.tips[i]
tvHeaderRight.text = ReadTipConfig.tips[i]
postEvent(EventBus.UP_CONFIG, true)
}
}
ll_footer_left.onClick {
llFooterLeft.onClick {
selector(items = ReadTipConfig.tips) { _, i ->
clearRepeat(i)
ReadTipConfig.tipFooterLeft = i
tv_footer_left.text = ReadTipConfig.tips[i]
tvFooterLeft.text = ReadTipConfig.tips[i]
postEvent(EventBus.UP_CONFIG, true)
}
}
ll_footer_middle.onClick {
llFooterMiddle.onClick {
selector(items = ReadTipConfig.tips) { _, i ->
clearRepeat(i)
ReadTipConfig.tipFooterMiddle = i
tv_footer_middle.text = ReadTipConfig.tips[i]
tvFooterMiddle.text = ReadTipConfig.tips[i]
postEvent(EventBus.UP_CONFIG, true)
}
}
ll_footer_right.onClick {
llFooterRight.onClick {
selector(items = ReadTipConfig.tips) { _, i ->
clearRepeat(i)
ReadTipConfig.tipFooterRight = i
tv_footer_right.text = ReadTipConfig.tips[i]
tvFooterRight.text = ReadTipConfig.tips[i]
postEvent(EventBus.UP_CONFIG, true)
}
}
ll_tip_color.onClick {
llTipColor.onClick {
selector(items = arrayListOf("跟随正文", "自定义")) { _, i ->
when (i) {
0 -> {
@ -173,27 +176,27 @@ class TipConfigDialog : BaseDialogFragment() {
if (repeat != none) {
if (tipHeaderLeft == repeat) {
tipHeaderLeft = none
tv_header_left.text = tips[none]
binding.tvHeaderLeft.text = tips[none]
}
if (tipHeaderMiddle == repeat) {
tipHeaderMiddle = none
tv_header_middle.text = tips[none]
binding.tvHeaderMiddle.text = tips[none]
}
if (tipHeaderRight == repeat) {
tipHeaderRight = none
tv_header_right.text = tips[none]
binding.tvHeaderRight.text = tips[none]
}
if (tipFooterLeft == repeat) {
tipFooterLeft = none
tv_footer_left.text = tips[none]
binding.tvFooterLeft.text = tips[none]
}
if (tipFooterMiddle == repeat) {
tipFooterMiddle = none
tv_footer_middle.text = tips[none]
binding.tvFooterMiddle.text = tips[none]
}
if (tipFooterRight == repeat) {
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.SimpleRecyclerAdapter
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.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.ui.widget.text.AutoCompleteTextView
import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.*
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 io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
import org.jetbrains.anko.sdk27.listeners.onClick
@ -44,6 +44,7 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
var selectedName: String? = null
private var durRegex: String? = null
lateinit var viewModel: TocRegexViewModel
private val binding by viewBinding(DialogTocRegexBinding::bind)
override fun onStart() {
super.onStart()
@ -61,28 +62,28 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
}
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setBackgroundColor(primaryColor)
binding.toolBar.setBackgroundColor(primaryColor)
durRegex = arguments?.getString("tocRegex")
tool_bar.setTitle(R.string.txt_toc_regex)
tool_bar.inflateMenu(R.menu.txt_toc_regex)
tool_bar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this)
binding.toolBar.setTitle(R.string.txt_toc_regex)
binding.toolBar.inflateMenu(R.menu.txt_toc_regex)
binding.toolBar.menu.applyTint(requireContext())
binding.toolBar.setOnMenuItemClickListener(this)
initView()
initData()
}
private fun initView() {
private fun initView() = with(binding) {
adapter = TocRegexAdapter(requireContext())
recycler_view.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(requireContext())
recyclerView.addItemDecoration(VerticalDivider(requireContext()))
recyclerView.adapter = adapter
val itemTouchCallback = ItemTouchCallback(adapter)
itemTouchCallback.isCanDrag = true
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(recycler_view)
tv_cancel.onClick {
ItemTouchHelper(itemTouchCallback).attachToRecyclerView(recyclerView)
tvCancel.onClick {
dismiss()
}
tv_ok.onClick {
tvOk.onClick {
adapter.getItems().forEach { tocRule ->
if (selectedName == tocRule.name) {
val callBack = activity as? CallBack
@ -139,27 +140,26 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
cacheUrls.add(0, defaultUrl)
}
requireContext().alert(titleResource = R.string.import_book_source_on_line) {
var editText: AutoCompleteTextView? = null
customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply {
editText = this.edit_view
edit_view.setFilterValues(cacheUrls)
edit_view.delCallBack = {
cacheUrls.remove(it)
aCache.put(importTocRuleKey, cacheUrls.joinToString(","))
}
val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
alertBinding.apply {
editView.setFilterValues(cacheUrls)
editView.delCallBack = {
cacheUrls.remove(it)
aCache.put(importTocRuleKey, cacheUrls.joinToString(","))
}
}
customView = alertBinding.root
okButton {
val text = editText?.text?.toString()
val text = alertBinding.editView.text?.toString()
text?.let {
if (!cacheUrls.contains(it)) {
cacheUrls.add(0, it)
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 ->
tool_bar.snackbar(msg)
binding.toolBar.snackbar(msg)
}
}
}
@ -171,19 +171,16 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
private fun editRule(rule: TxtTocRule? = null) {
val tocRule = rule?.copy() ?: TxtTocRule()
requireContext().alert(titleResource = R.string.txt_toc_regex) {
var rootView: View? = null
customView {
LayoutInflater.from(requireContext())
.inflate(R.layout.dialog_toc_regex_edit, null).apply {
rootView = this
tv_rule_name.setText(tocRule.name)
tv_rule_regex.setText(tocRule.rule)
}
val alertBinding = DialogTocRegexEditBinding.inflate(layoutInflater)
alertBinding.apply {
tvRuleName.setText(tocRule.name)
tvRuleRegex.setText(tocRule.rule)
}
customView = alertBinding.root
okButton {
rootView?.apply {
tocRule.name = tv_rule_name.text.toString()
tocRule.rule = tv_rule_regex.text.toString()
alertBinding.apply {
tocRule.name = tvRuleName.text.toString()
tocRule.rule = tvRuleRegex.text.toString()
viewModel.saveRule(tocRule)
}
}
@ -192,31 +189,36 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
}
inner class TocRegexAdapter(context: Context) :
SimpleRecyclerAdapter<TxtTocRule>(context, R.layout.item_toc_regex),
SimpleRecyclerAdapter<TxtTocRule, ItemTocRegexBinding>(context),
ItemTouchCallback.Callback {
override fun convert(holder: ItemViewHolder, item: TxtTocRule, payloads: MutableList<Any>) {
holder.itemView.apply {
override fun convert(
holder: ItemViewHolder,
binding: ItemTocRegexBinding,
item: TxtTocRule,
payloads: MutableList<Any>
) {
binding.apply {
if (payloads.isEmpty()) {
setBackgroundColor(context.backgroundColor)
rb_regex_name.text = item.name
rb_regex_name.isChecked = item.name == selectedName
swt_enabled.isChecked = item.enable
root.setBackgroundColor(context.backgroundColor)
rbRegexName.text = item.name
rbRegexName.isChecked = item.name == selectedName
swtEnabled.isChecked = item.enable
} else {
rb_regex_name.isChecked = item.name == selectedName
rbRegexName.isChecked = item.name == selectedName
}
}
}
override fun registerListener(holder: ItemViewHolder) {
holder.itemView.apply {
rb_regex_name.setOnCheckedChangeListener { buttonView, isChecked ->
override fun registerListener(holder: ItemViewHolder, binding: ItemTocRegexBinding) {
binding.apply {
rbRegexName.setOnCheckedChangeListener { buttonView, isChecked ->
if (buttonView.isPressed && isChecked) {
selectedName = getItem(holder.layoutPosition)?.name
updateItems(0, itemCount - 1, true)
}
}
swt_enabled.setOnCheckedChangeListener { buttonView, isChecked ->
swtEnabled.setOnCheckedChangeListener { buttonView, isChecked ->
if (buttonView.isPressed) {
getItem(holder.layoutPosition)?.let {
it.enable = isChecked
@ -226,10 +228,10 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
}
}
}
iv_edit.onClick {
ivEdit.onClick {
editRule(getItem(holder.layoutPosition))
}
iv_delete.onClick {
ivDelete.onClick {
getItem(holder.layoutPosition)?.let { item ->
launch(IO) {
App.db.txtTocRule().delete(item)

@ -1,23 +1,27 @@
package io.legado.app.ui.book.search
import android.content.Context
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
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
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>) {
with(holder.itemView) {
text_view.text = item.name
override fun convert(
holder: ItemViewHolder,
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 {
onClick {
getItem(holder.layoutPosition)?.let {

@ -1,12 +1,11 @@
package io.legado.app.ui.book.search
import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.SearchKeyword
import io.legado.app.databinding.ItemFilletTextBinding
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.GlobalScope
import kotlinx.coroutines.launch
@ -15,17 +14,22 @@ import org.jetbrains.anko.sdk27.listeners.onLongClick
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)
override fun convert(holder: ItemViewHolder, item: SearchKeyword, payloads: MutableList<Any>) {
with(holder.itemView) {
text_view.text = item.word
override fun convert(
holder: ItemViewHolder,
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 {
onClick {
getItem(holder.layoutPosition)?.let {

@ -2,31 +2,33 @@ package io.legado.app.ui.book.search
import android.content.Context
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.SimpleRecyclerAdapter
import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.ItemSearchBinding
import io.legado.app.utils.gone
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
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
if (bundle == null) {
bind(holder.itemView, item)
bind(binding, item)
} 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 {
onClick {
getItem(holder.layoutPosition)?.let {
@ -36,45 +38,45 @@ class SearchAdapter(context: Context, val callBack: CallBack) :
}
}
private fun bind(itemView: View, searchBook: SearchBook) {
with(itemView) {
tv_name.text = searchBook.name
tv_author.text = context.getString(R.string.author_show, searchBook.author)
bv_originCount.setBadgeCount(searchBook.origins.size)
upLasted(itemView, searchBook.latestChapterTitle)
private fun bind(binding: ItemSearchBinding, searchBook: SearchBook) {
with(binding) {
tvName.text = searchBook.name
tvAuthor.text = context.getString(R.string.author_show, searchBook.author)
bvOriginCount.setBadgeCount(searchBook.origins.size)
upLasted(binding, searchBook.latestChapterTitle)
if (searchBook.intro.isNullOrEmpty()) {
tv_introduce.text =
tvIntroduce.text =
context.getString(R.string.intro_show_null)
} else {
tv_introduce.text =
tvIntroduce.text =
context.getString(R.string.intro_show, searchBook.intro)
}
upKind(itemView, searchBook.getKindList())
iv_cover.load(searchBook.coverUrl, searchBook.name, searchBook.author)
upKind(binding, searchBook.getKindList())
ivCover.load(searchBook.coverUrl, searchBook.name, searchBook.author)
}
}
private fun bindChange(itemView: View, searchBook: SearchBook, bundle: Bundle) {
with(itemView) {
private fun bindChange(binding: ItemSearchBinding, searchBook: SearchBook, bundle: Bundle) {
with(binding) {
bundle.keySet().map {
when (it) {
"name" -> tv_name.text = searchBook.name
"author" -> tv_author.text =
"name" -> tvName.text = searchBook.name
"author" -> tvAuthor.text =
context.getString(R.string.author_show, searchBook.author)
"origins" -> bv_originCount.setBadgeCount(searchBook.origins.size)
"last" -> upLasted(itemView, searchBook.latestChapterTitle)
"origins" -> bvOriginCount.setBadgeCount(searchBook.origins.size)
"last" -> upLasted(binding, searchBook.latestChapterTitle)
"intro" -> {
if (searchBook.intro.isNullOrEmpty()) {
tv_introduce.text =
tvIntroduce.text =
context.getString(R.string.intro_show_null)
} else {
tv_introduce.text =
tvIntroduce.text =
context.getString(R.string.intro_show, searchBook.intro)
}
}
"kind" -> upKind(itemView, searchBook.getKindList())
"cover" -> iv_cover.load(
"kind" -> upKind(binding, searchBook.getKindList())
"cover" -> ivCover.load(
searchBook.coverUrl,
searchBook.name,
searchBook.author
@ -84,27 +86,24 @@ class SearchAdapter(context: Context, val callBack: CallBack) :
}
}
private fun upLasted(itemView: View, latestChapterTitle: String?) {
with(itemView) {
private fun upLasted(binding: ItemSearchBinding, latestChapterTitle: String?) {
with(binding) {
if (latestChapterTitle.isNullOrEmpty()) {
tv_lasted.gone()
tvLasted.gone()
} else {
tv_lasted.text =
context.getString(
R.string.lasted_show,
latestChapterTitle
)
tv_lasted.visible()
tvLasted.text =
context.getString(R.string.lasted_show, latestChapterTitle)
tvLasted.visible()
}
}
}
private fun upKind(itemView: View, kinds: List<String>) = with(itemView) {
private fun upKind(binding: ItemSearchBinding, kinds: List<String>) = with(binding) {
if (kinds.isEmpty()) {
ll_kind.gone()
llKind.gone()
} else {
ll_kind.visible()
ll_kind.setLabels(kinds)
llKind.visible()
llKind.setLabels(kinds)
}
}

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

@ -5,29 +5,35 @@ import android.view.View
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
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) :
SimpleRecyclerAdapter<String>(context, R.layout.item_log) {
override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList<Any>) {
holder.itemView.apply {
if (text_view.getTag(R.id.tag1) == null) {
SimpleRecyclerAdapter<String, ItemLogBinding>(context) {
override fun convert(
holder: ItemViewHolder,
binding: ItemLogBinding,
item: String,
payloads: MutableList<Any>
) {
binding.apply {
if (textView.getTag(R.id.tag1) == null) {
val listener = object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View) {
text_view.isCursorVisible = false
text_view.isCursorVisible = true
textView.isCursorVisible = false
textView.isCursorVisible = true
}
override fun onViewDetachedFromWindow(v: View) {}
}
text_view.addOnAttachStateChangeListener(listener)
text_view.setTag(R.id.tag1, listener)
textView.addOnAttachStateChangeListener(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
}
}

@ -7,7 +7,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
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>() {
@ -18,9 +18,9 @@ class BookSourceEditAdapter : RecyclerView.Adapter<BookSourceEditAdapter.MyViewH
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_source_edit, parent, false)
return MyViewHolder(view)
val binding = ItemSourceEditBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
return MyViewHolder(binding)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
@ -31,8 +31,9 @@ class BookSourceEditAdapter : RecyclerView.Adapter<BookSourceEditAdapter.MyViewH
return editEntities.size
}
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun bind(editEntity: EditEntity) = with(itemView) {
class MyViewHolder(val binding: ItemSourceEditBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(editEntity: EditEntity) = with(binding) {
if (editText.getTag(R.id.tag1) == null) {
val listener = object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View) {
@ -55,7 +56,7 @@ class BookSourceEditAdapter : RecyclerView.Adapter<BookSourceEditAdapter.MyViewH
}
}
editText.setText(editEntity.value)
textInputLayout.hint = context.getString(editEntity.hint)
textInputLayout.hint = itemView.context.getString(editEntity.hint)
val textWatcher = object : TextWatcher {
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.SimpleRecyclerAdapter
import io.legado.app.data.entities.BookSource
import io.legado.app.databinding.ItemBookSourceBinding
import io.legado.app.lib.theme.backgroundColor
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
import io.legado.app.ui.widget.recycler.ItemTouchCallback.Callback
import io.legado.app.utils.invisible
import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_book_source.view.*
import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.*
class BookSourceAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<BookSource>(context, R.layout.item_book_source),
SimpleRecyclerAdapter<BookSource, ItemBookSourceBinding>(context),
Callback {
private val selected = linkedSetOf<BookSource>()
@ -57,41 +57,46 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
return selection.sortedBy { it.customOrder }
}
override fun convert(holder: ItemViewHolder, item: BookSource, payloads: MutableList<Any>) {
with(holder.itemView) {
override fun convert(
holder: ItemViewHolder,
binding: ItemBookSourceBinding,
item: BookSource,
payloads: MutableList<Any>
) {
with(binding) {
val payload = payloads.getOrNull(0) as? Bundle
if (payload == null) {
this.setBackgroundColor(context.backgroundColor)
root.setBackgroundColor(context.backgroundColor)
if (item.bookSourceGroup.isNullOrEmpty()) {
cb_book_source.text = item.bookSourceName
cbBookSource.text = item.bookSourceName
} else {
cb_book_source.text =
cbBookSource.text =
String.format("%s (%s)", item.bookSourceName, item.bookSourceGroup)
}
swt_enabled.isChecked = item.enabled
cb_book_source.isChecked = selected.contains(item)
upShowExplore(iv_explore, item)
swtEnabled.isChecked = item.enabled
cbBookSource.isChecked = selected.contains(item)
upShowExplore(ivExplore, item)
} else {
payload.keySet().map {
when (it) {
"selected" -> cb_book_source.isChecked = selected.contains(item)
"selected" -> cbBookSource.isChecked = selected.contains(item)
"name", "group" -> if (item.bookSourceGroup.isNullOrEmpty()) {
cb_book_source.text = item.bookSourceName
cbBookSource.text = item.bookSourceName
} else {
cb_book_source.text =
cbBookSource.text =
String.format("%s (%s)", item.bookSourceName, item.bookSourceGroup)
}
"enabled" -> swt_enabled.isChecked = payload.getBoolean(it)
"showExplore" -> upShowExplore(iv_explore, item)
"enabled" -> swtEnabled.isChecked = payload.getBoolean(it)
"showExplore" -> upShowExplore(ivExplore, item)
}
}
}
}
}
override fun registerListener(holder: ItemViewHolder) {
holder.itemView.apply {
swt_enabled.setOnCheckedChangeListener { view, checked ->
override fun registerListener(holder: ItemViewHolder, binding: ItemBookSourceBinding) {
binding.apply {
swtEnabled.setOnCheckedChangeListener { view, checked ->
getItem(holder.layoutPosition)?.let {
if (view.isPressed) {
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 {
if (view.isPressed) {
if (checked) {
@ -111,13 +116,13 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
}
}
}
iv_edit.onClick {
ivEdit.onClick {
getItem(holder.layoutPosition)?.let {
callBack.edit(it)
}
}
iv_menu_more.onClick {
showMenu(iv_menu_more, holder.layoutPosition)
ivMenuMore.onClick {
showMenu(ivMenuMore, holder.layoutPosition)
}
}
}

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

@ -1,14 +1,12 @@
package io.legado.app.ui.book.toc
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.paging.PagedListAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
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.onLongClick
@ -31,7 +29,9 @@ class BookmarkAdapter(val callback: Callback) : PagedListAdapter<Bookmark, Bookm
}
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) {
@ -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) {
tv_chapter_name.text = bookmark.chapterName
tv_content.text = bookmark.content
fun bind(bookmark: Bookmark, callback: Callback?) = with(binding) {
tvChapterName.text = bookmark.chapterName
tvContent.text = bookmark.content
itemView.onClick {
callback?.onClick(bookmark)
}

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

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

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

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

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

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

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

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

@ -2,52 +2,59 @@ package io.legado.app.ui.main.bookshelf.books
import android.content.Context
import android.os.Bundle
import android.view.View
import io.legado.app.R
import android.view.ViewGroup
import androidx.viewbinding.ViewBinding
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.constant.BookType
import io.legado.app.data.entities.Book
import io.legado.app.databinding.ItemBookshelfGridBinding
import io.legado.app.lib.theme.ATH
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.onLongClick
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
with(holder.itemView) {
if (bundle == null) {
ATH.applyBackgroundTint(this)
tv_name.text = item.name
iv_cover.load(item.getDisplayCover(), item.name, item.author)
upRefresh(this, item)
} else {
bundle.keySet().forEach {
when (it) {
"name" -> tv_name.text = item.name
"cover" -> iv_cover.load(item.getDisplayCover(), item.name, item.author)
"refresh" -> upRefresh(this, item)
}
if (bundle == null) {
ATH.applyBackgroundTint(binding.root)
binding.tvName.text = item.name
binding.ivCover.load(item.getDisplayCover(), item.name, item.author)
upRefresh(binding, item)
} else {
bundle.keySet().forEach {
when (it) {
"name" -> binding.tvName.text = item.name
"cover" -> binding.ivCover.load(item.getDisplayCover(), item.name, item.author)
"refresh" -> upRefresh(binding, 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)) {
bv_unread.invisible()
rl_loading.show()
binding.bvUnread.invisible()
binding.rlLoading.show()
} else {
rl_loading.hide()
bv_unread.setBadgeCount(item.getUnreadChapterNum())
bv_unread.setHighlight(item.lastCheckCount > 0)
binding.rlLoading.hide()
binding.bvUnread.setBadgeCount(item.getUnreadChapterNum())
binding.bvUnread.setHighlight(item.lastCheckCount > 0)
}
}
override fun registerListener(holder: ItemViewHolder) {
override fun registerListener(holder: ItemViewHolder, binding: ItemBookshelfGridBinding) {
holder.itemView.apply {
onClick {
getItem(holder.layoutPosition)?.let {

@ -2,58 +2,59 @@ package io.legado.app.ui.main.bookshelf.books
import android.content.Context
import android.os.Bundle
import android.view.View
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.constant.BookType
import io.legado.app.data.entities.Book
import io.legado.app.databinding.ItemBookshelfListBinding
import io.legado.app.lib.theme.ATH
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.onLongClick
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
with(holder.itemView) {
if (bundle == null) {
ATH.applyBackgroundTint(this)
tv_name.text = item.name
tv_author.text = item.author
tv_read.text = item.durChapterTitle
tv_last.text = item.latestChapterTitle
iv_cover.load(item.getDisplayCover(), item.name, item.author)
upRefresh(this, item)
} else {
tv_read.text = item.durChapterTitle
tv_last.text = item.latestChapterTitle
bundle.keySet().forEach {
when (it) {
"name" -> tv_name.text = item.name
"author" -> tv_author.text = item.author
"cover" -> iv_cover.load(item.getDisplayCover(), item.name, item.author)
"refresh" -> upRefresh(this, item)
}
if (bundle == null) {
ATH.applyBackgroundTint(binding.root)
binding.tvName.text = item.name
binding.tvAuthor.text = item.author
binding.tvRead.text = item.durChapterTitle
binding.tvLast.text = item.latestChapterTitle
binding.ivCover.load(item.getDisplayCover(), item.name, item.author)
upRefresh(binding, item)
} else {
binding.tvRead.text = item.durChapterTitle
binding.tvLast.text = item.latestChapterTitle
bundle.keySet().forEach {
when (it) {
"name" -> binding.tvName.text = item.name
"author" -> binding.tvAuthor.text = item.author
"cover" -> binding.ivCover.load(item.getDisplayCover(), item.name, item.author)
"refresh" -> upRefresh(binding, 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)) {
bv_unread.invisible()
rl_loading.show()
binding.bvUnread.invisible()
binding.rlLoading.show()
} else {
rl_loading.hide()
bv_unread.setHighlight(item.lastCheckCount > 0)
bv_unread.setBadgeCount(item.getUnreadChapterNum())
binding.rlLoading.hide()
binding.bvUnread.setHighlight(item.lastCheckCount > 0)
binding.bvUnread.setBadgeCount(item.getUnreadChapterNum())
}
}
override fun registerListener(holder: ItemViewHolder) {
override fun registerListener(holder: ItemViewHolder, binding: ItemBookshelfListBinding) {
holder.itemView.apply {
onClick {
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.PreferKey
import io.legado.app.data.entities.Book
import io.legado.app.databinding.FragmentBooksBinding
import io.legado.app.help.AppConfig
import io.legado.app.help.IntentDataHelp
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.observeEvent
import io.legado.app.utils.startActivity
import kotlinx.android.synthetic.main.fragment_books.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
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
get() = getViewModelOfActivity(MainViewModel::class.java)
private lateinit var booksAdapter: BaseBooksAdapter
private lateinit var booksAdapter: BaseBooksAdapter<*>
private var bookshelfLiveData: LiveData<List<Book>>? = null
private var position = 0
private var groupId = -1L
@ -65,35 +67,35 @@ class BooksFragment : BaseFragment(R.layout.fragment_books),
}
private fun initRecyclerView() {
ATH.applyEdgeEffectColor(rv_bookshelf)
refresh_layout.setColorSchemeColors(accentColor)
refresh_layout.setOnRefreshListener {
refresh_layout.isRefreshing = false
ATH.applyEdgeEffectColor(binding.rvBookshelf)
binding.refreshLayout.setColorSchemeColors(accentColor)
binding.refreshLayout.setOnRefreshListener {
binding.refreshLayout.isRefreshing = false
activityViewModel.upToc(booksAdapter.getItems())
}
val bookshelfLayout = getPrefInt(PreferKey.bookshelfLayout)
if (bookshelfLayout == 0) {
rv_bookshelf.layoutManager = LinearLayoutManager(context)
binding.rvBookshelf.layoutManager = LinearLayoutManager(context)
booksAdapter = BooksAdapterList(requireContext(), this)
} else {
rv_bookshelf.layoutManager = GridLayoutManager(context, bookshelfLayout + 2)
binding.rvBookshelf.layoutManager = GridLayoutManager(context, bookshelfLayout + 2)
booksAdapter = BooksAdapterGrid(requireContext(), this)
}
rv_bookshelf.adapter = booksAdapter
binding.rvBookshelf.adapter = booksAdapter
booksAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
val layoutManager = rv_bookshelf.layoutManager
val layoutManager = binding.rvBookshelf.layoutManager
if (positionStart == 0 && layoutManager is LinearLayoutManager) {
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) {
val layoutManager = rv_bookshelf.layoutManager
val layoutManager = binding.rvBookshelf.layoutManager
if (toPosition == 0 && layoutManager is LinearLayoutManager) {
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)
}.apply {
observe(viewLifecycleOwner) { list ->
tv_empty_msg.isGone = list.isNotEmpty()
binding.tvEmptyMsg.isGone = list.isNotEmpty()
val books = when (getPrefInt(PreferKey.bookshelfSort)) {
1 -> list.sortedByDescending { it.latestChapterTime }
2 -> list.sortedBy { it.name }
@ -129,9 +131,9 @@ class BooksFragment : BaseFragment(R.layout.fragment_books),
fun gotoTop() {
if (AppConfig.isEInkMode) {
rv_bookshelf.scrollToPosition(0)
binding.rvBookshelf.scrollToPosition(0)
} 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.SimpleRecyclerAdapter
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.lib.theme.accentColor
import io.legado.app.utils.ACache
import io.legado.app.utils.dp
import io.legado.app.utils.gone
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 org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onLongClick
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 scrollTo = -1
override fun convert(holder: ItemViewHolder, item: BookSource, payloads: MutableList<Any>) {
with(holder.itemView) {
override fun convert(
holder: ItemViewHolder,
binding: ItemFindBookBinding,
item: BookSource,
payloads: MutableList<Any>
) {
with(binding) {
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 {
setPadding(16.dp, 12.dp, 16.dp, 0)
root.setPadding(16.dp, 12.dp, 16.dp, 0)
}
if (payloads.isEmpty()) {
tv_name.text = item.bookSourceName
tvName.text = item.bookSourceName
}
if (exIndex == holder.layoutPosition) {
iv_status.setImageResource(R.drawable.ic_arrow_down)
rotate_loading.loadingColor = context.accentColor
rotate_loading.show()
ivStatus.setImageResource(R.drawable.ic_arrow_down)
rotateLoading.loadingColor = context.accentColor
rotateLoading.show()
if (scrollTo >= 0) {
callBack.scrollTo(scrollTo)
}
@ -48,15 +53,18 @@ class ExploreAdapter(context: Context, private val scope: CoroutineScope, val ca
item.getExploreKinds()
}.onSuccess { kindList ->
if (!kindList.isNullOrEmpty()) {
gl_child.visible()
gl_child.removeAllViews()
glChild.visible()
glChild.removeAllViews()
kindList.map { kind ->
val tv = LayoutInflater.from(context)
.inflate(R.layout.item_fillet_text, gl_child, false)
gl_child.addView(tv)
tv.text_view.text = kind.title
val tv = ItemFilletTextBinding.inflate(
LayoutInflater.from(context),
glChild,
false
)
glChild.addView(tv.root)
tv.textView.text = kind.title
if (!kind.url.isNullOrEmpty()) {
tv.text_view.onClick {
tv.textView.onClick {
callBack.openExplore(
item.bookSourceUrl,
kind.title,
@ -67,23 +75,23 @@ class ExploreAdapter(context: Context, private val scope: CoroutineScope, val ca
}
}
}.onFinally {
rotate_loading.hide()
rotateLoading.hide()
if (scrollTo >= 0) {
callBack.scrollTo(scrollTo)
scrollTo = -1
}
}
} else {
iv_status.setImageResource(R.drawable.ic_arrow_right)
rotate_loading.hide()
gl_child.gone()
binding.ivStatus.setImageResource(R.drawable.ic_arrow_right)
binding.rotateLoading.hide()
binding.glChild.gone()
}
}
}
override fun registerListener(holder: ItemViewHolder) {
holder.itemView.apply {
ll_title.onClick {
override fun registerListener(holder: ItemViewHolder, binding: ItemFindBookBinding) {
binding.apply {
llTitle.onClick {
val position = holder.layoutPosition
val oldEx = exIndex
exIndex = if (exIndex == position) -1 else position
@ -94,8 +102,8 @@ class ExploreAdapter(context: Context, private val scope: CoroutineScope, val ca
notifyItemChanged(position, false)
}
}
ll_title.onLongClick {
showMenu(ll_title, holder.layoutPosition)
llTitle.onLongClick {
showMenu(llTitle, holder.layoutPosition)
}
}
}

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

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

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

@ -2,53 +2,49 @@ package io.legado.app.ui.widget.recycler
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.FrameLayout
import io.legado.app.R
import io.legado.app.databinding.ViewLoadMoreBinding
import io.legado.app.utils.invisible
import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.view_load_more.view.*
@Suppress("unused")
class LoadMoreView(context: Context, attrs: AttributeSet? = null) : FrameLayout(context, attrs) {
private val binding = ViewLoadMoreBinding.inflate(LayoutInflater.from(context), this)
var hasMore = true
private set
init {
View.inflate(context, R.layout.view_load_more, this)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
}
fun startLoad() {
tv_text.invisible()
rotate_loading.show()
binding.tvText.invisible()
binding.rotateLoading.show()
}
fun stopLoad() {
rotate_loading.hide()
binding.rotateLoading.hide()
}
fun hasMore() {
hasMore = true
tv_text.invisible()
rotate_loading.show()
binding.tvText.invisible()
binding.rotateLoading.show()
}
fun noMore(msg: String? = null) {
hasMore = false
rotate_loading.hide()
binding.rotateLoading.hide()
if (msg != null) {
tv_text.text = msg
binding.tvText.text = msg
} 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background_menu"

Loading…
Cancel
Save