viewBinding

pull/517/head
gedoor 5 years ago
parent 1225af46a4
commit 8a57fe3b28
  1. 3
      app/src/main/java/io/legado/app/data/entities/rule/BookInfoRule.kt
  2. 2
      app/src/main/java/io/legado/app/data/entities/rule/ContentRule.kt
  3. 2
      app/src/main/java/io/legado/app/data/entities/rule/ExploreRule.kt
  4. 3
      app/src/main/java/io/legado/app/data/entities/rule/SearchRule.kt
  5. 2
      app/src/main/java/io/legado/app/data/entities/rule/TocRule.kt
  6. 34
      app/src/main/java/io/legado/app/ui/filepicker/FilePickerDialog.kt
  7. 30
      app/src/main/java/io/legado/app/ui/filepicker/adapter/FileAdapter.kt
  8. 22
      app/src/main/java/io/legado/app/ui/filepicker/adapter/PathAdapter.kt
  9. 4
      app/src/main/java/io/legado/app/ui/main/MainActivity.kt
  10. 6
      app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksAdapterGrid.kt
  11. 78
      app/src/main/java/io/legado/app/ui/replace/GroupManageDialog.kt
  12. 47
      app/src/main/java/io/legado/app/ui/replace/ReplaceRuleAdapter.kt
  13. 42
      app/src/main/java/io/legado/app/ui/replace/edit/ReplaceEditActivity.kt
  14. 16
      app/src/main/java/io/legado/app/ui/rss/article/BaseRssArticlesAdapter.kt
  15. 41
      app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter.kt
  16. 80
      app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter1.kt
  17. 80
      app/src/main/java/io/legado/app/ui/rss/article/RssArticlesAdapter2.kt
  18. 42
      app/src/main/java/io/legado/app/ui/rss/article/RssArticlesFragment.kt
  19. 7
      app/src/main/java/io/legado/app/ui/rss/article/RssSortViewModel.kt
  20. 28
      app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesAdapter.kt
  21. 27
      app/src/main/java/io/legado/app/ui/rss/source/debug/RssSourceDebugAdapter.kt
  22. 17
      app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditAdapter.kt
  23. 80
      app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt
  24. 45
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceAdapter.kt
  25. 31
      app/src/main/java/io/legado/app/ui/widget/KeyboardToolPop.kt
  26. 59
      app/src/main/java/io/legado/app/ui/widget/SelectActionBar.kt
  27. 7
      app/src/main/java/io/legado/app/ui/widget/dialog/PhotoDialog.kt
  28. 15
      app/src/main/java/io/legado/app/ui/widget/dialog/TextDialog.kt
  29. 42
      app/src/main/java/io/legado/app/ui/widget/dialog/TextListDialog.kt
  30. 6
      app/src/main/java/io/legado/app/ui/widget/dynamiclayout/DynamicFrameLayout.kt
  31. 26
      app/src/main/java/io/legado/app/ui/widget/font/FontAdapter.kt
  32. 18
      app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt
  33. 3
      app/src/main/java/io/legado/app/ui/widget/number/NumberPickerDialog.kt
  34. 26
      app/src/main/java/io/legado/app/ui/widget/prefs/IconListPreference.kt
  35. 11
      app/src/main/java/io/legado/app/ui/widget/text/AutoCompleteTextView.kt
  36. 4
      app/src/main/res/layout/view_dynamic.xml

@ -1,7 +1,8 @@
package io.legado.app.data.entities.rule package io.legado.app.data.entities.rule
import android.os.Parcelable import android.os.Parcelable
import kotlinx.android.parcel.Parcelize import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
data class BookInfoRule( data class BookInfoRule(

@ -1,7 +1,7 @@
package io.legado.app.data.entities.rule package io.legado.app.data.entities.rule
import android.os.Parcelable import android.os.Parcelable
import kotlinx.android.parcel.Parcelize import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
data class ContentRule( data class ContentRule(

@ -1,7 +1,7 @@
package io.legado.app.data.entities.rule package io.legado.app.data.entities.rule
import android.os.Parcelable import android.os.Parcelable
import kotlinx.android.parcel.Parcelize import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
data class ExploreRule( data class ExploreRule(

@ -1,7 +1,8 @@
package io.legado.app.data.entities.rule package io.legado.app.data.entities.rule
import android.os.Parcelable import android.os.Parcelable
import kotlinx.android.parcel.Parcelize import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
data class SearchRule( data class SearchRule(

@ -1,7 +1,7 @@
package io.legado.app.data.entities.rule package io.legado.app.data.entities.rule
import android.os.Parcelable import android.os.Parcelable
import kotlinx.android.parcel.Parcelize import kotlinx.parcelize.Parcelize
@Parcelize @Parcelize
data class TocRule( data class TocRule(

@ -14,12 +14,13 @@ import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R import io.legado.app.R
import io.legado.app.databinding.DialogFileChooserBinding
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.filepicker.adapter.FileAdapter import io.legado.app.ui.filepicker.adapter.FileAdapter
import io.legado.app.ui.filepicker.adapter.PathAdapter import io.legado.app.ui.filepicker.adapter.PathAdapter
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_file_chooser.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import java.io.File import java.io.File
@ -61,6 +62,7 @@ class FilePickerDialog : DialogFragment(),
} }
} }
private val binding by viewBinding(DialogFileChooserBinding::bind)
override var allowExtensions: Array<String>? = null override var allowExtensions: Array<String>? = null
override val isSelectDir: Boolean override val isSelectDir: Boolean
get() = mode == DIRECTORY get() = mode == DIRECTORY
@ -92,7 +94,7 @@ class FilePickerDialog : DialogFragment(),
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
tool_bar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
view.setBackgroundResource(R.color.background_card) view.setBackgroundResource(R.color.background_card)
arguments?.let { arguments?.let {
requestCode = it.getInt("requestCode") requestCode = it.getInt("requestCode")
@ -107,7 +109,7 @@ class FilePickerDialog : DialogFragment(),
allowExtensions = it.getStringArray("allowExtensions") allowExtensions = it.getStringArray("allowExtensions")
menus = it.getStringArray("menus") menus = it.getStringArray("menus")
} }
tool_bar.title = title ?: let { binding.toolBar.title = title ?: let {
if (isSelectDir) { if (isSelectDir) {
getString(R.string.folder_chooser) getString(R.string.folder_chooser)
} else { } else {
@ -120,29 +122,29 @@ class FilePickerDialog : DialogFragment(),
} }
private fun initMenu() { private fun initMenu() {
tool_bar.inflateMenu(R.menu.file_chooser) binding.toolBar.inflateMenu(R.menu.file_chooser)
if (isSelectDir) { if (isSelectDir) {
tool_bar.menu.findItem(R.id.menu_ok).isVisible = true binding.toolBar.menu.findItem(R.id.menu_ok).isVisible = true
} }
menus?.let { menus?.let {
it.forEach { menuTitle -> it.forEach { menuTitle ->
tool_bar.menu.add(menuTitle) binding.toolBar.menu.add(menuTitle)
} }
} }
tool_bar.menu.applyTint(requireContext()) binding.toolBar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this) binding.toolBar.setOnMenuItemClickListener(this)
} }
private fun initContentView() { private fun initContentView() {
fileAdapter = FileAdapter(requireContext(), this) fileAdapter = FileAdapter(requireContext(), this)
pathAdapter = PathAdapter(requireContext(), this) pathAdapter = PathAdapter(requireContext(), this)
rv_file.addItemDecoration(VerticalDivider(requireContext())) binding.rvFile.addItemDecoration(VerticalDivider(requireContext()))
rv_file.layoutManager = LinearLayoutManager(activity) binding.rvFile.layoutManager = LinearLayoutManager(activity)
rv_file.adapter = fileAdapter binding.rvFile.adapter = fileAdapter
rv_path.layoutManager = LinearLayoutManager(activity, RecyclerView.HORIZONTAL, false) binding.rvPath.layoutManager = LinearLayoutManager(activity, RecyclerView.HORIZONTAL, false)
rv_path.adapter = pathAdapter binding.rvPath.adapter = pathAdapter
} }
@ -200,10 +202,10 @@ class FilePickerDialog : DialogFragment(),
adapterCount-- adapterCount--
} }
if (adapterCount < 1) { if (adapterCount < 1) {
tv_empty.visible() binding.tvEmpty.visible()
tv_empty.setText(R.string.empty) binding.tvEmpty.setText(R.string.empty)
} else { } else {
tv_empty.gone() binding.tvEmpty.gone()
} }
} }

@ -2,9 +2,9 @@ package io.legado.app.ui.filepicker.adapter
import android.content.Context import android.content.Context
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.databinding.ItemFileFilepickerBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.lib.theme.getPrimaryDisabledTextColor import io.legado.app.lib.theme.getPrimaryDisabledTextColor
import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.getPrimaryTextColor
@ -12,14 +12,13 @@ import io.legado.app.ui.filepicker.entity.FileItem
import io.legado.app.ui.filepicker.utils.ConvertUtils import io.legado.app.ui.filepicker.utils.ConvertUtils
import io.legado.app.ui.filepicker.utils.FilePickerIcon import io.legado.app.ui.filepicker.utils.FilePickerIcon
import io.legado.app.utils.FileUtils import io.legado.app.utils.FileUtils
import kotlinx.android.synthetic.main.item_path_filepicker.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.io.File import java.io.File
import java.util.* import java.util.*
class FileAdapter(context: Context, val callBack: CallBack) : class FileAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<FileItem>(context, R.layout.item_file_filepicker) { SimpleRecyclerAdapter<FileItem, ItemFileFilepickerBinding>(context) {
private var rootPath: String? = null private var rootPath: String? = null
var currentPath: String? = null var currentPath: String? = null
private set private set
@ -86,29 +85,34 @@ class FileAdapter(context: Context, val callBack: CallBack) :
} }
override fun convert(holder: ItemViewHolder, item: FileItem, payloads: MutableList<Any>) { override fun convert(
holder.itemView.apply { holder: ItemViewHolder,
image_view.setImageDrawable(item.icon) binding: ItemFileFilepickerBinding,
text_view.text = item.name item: FileItem,
payloads: MutableList<Any>
) {
binding.apply {
imageView.setImageDrawable(item.icon)
textView.text = item.name
if (item.isDirectory) { if (item.isDirectory) {
text_view.setTextColor(primaryTextColor) textView.setTextColor(primaryTextColor)
} else { } else {
if (callBack.isSelectDir) { if (callBack.isSelectDir) {
text_view.setTextColor(disabledTextColor) textView.setTextColor(disabledTextColor)
} else { } else {
callBack.allowExtensions?.let { callBack.allowExtensions?.let {
if (it.isEmpty() || it.contains(FileUtils.getExtension(item.path))) { if (it.isEmpty() || it.contains(FileUtils.getExtension(item.path))) {
text_view.setTextColor(primaryTextColor) textView.setTextColor(primaryTextColor)
} else { } else {
text_view.setTextColor(disabledTextColor) textView.setTextColor(disabledTextColor)
} }
} ?: text_view.setTextColor(primaryTextColor) } ?: textView.setTextColor(primaryTextColor)
} }
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemFileFilepickerBinding) {
holder.itemView.onClick { holder.itemView.onClick {
callBack.onFileClick(holder.layoutPosition) callBack.onFileClick(holder.layoutPosition)
} }

@ -2,18 +2,17 @@ package io.legado.app.ui.filepicker.adapter
import android.content.Context import android.content.Context
import android.os.Environment import android.os.Environment
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.databinding.ItemPathFilepickerBinding
import io.legado.app.ui.filepicker.utils.ConvertUtils import io.legado.app.ui.filepicker.utils.ConvertUtils
import io.legado.app.ui.filepicker.utils.FilePickerIcon import io.legado.app.ui.filepicker.utils.FilePickerIcon
import kotlinx.android.synthetic.main.item_path_filepicker.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.* import java.util.*
class PathAdapter(context: Context, val callBack: CallBack) : class PathAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<String>(context, R.layout.item_path_filepicker) { SimpleRecyclerAdapter<String, ItemPathFilepickerBinding>(context) {
private val paths = LinkedList<String>() private val paths = LinkedList<String>()
private val arrowIcon = ConvertUtils.toDrawable(FilePickerIcon.getArrow()) private val arrowIcon = ConvertUtils.toDrawable(FilePickerIcon.getArrow())
@ -44,14 +43,19 @@ class PathAdapter(context: Context, val callBack: CallBack) :
setItems(paths) setItems(paths)
} }
override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList<Any>) { override fun convert(
holder.itemView.apply { holder: ItemViewHolder,
text_view.text = item binding: ItemPathFilepickerBinding,
image_view.setImageDrawable(arrowIcon) item: String,
payloads: MutableList<Any>
) {
binding.apply {
textView.text = item
imageView.setImageDrawable(arrowIcon)
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemPathFilepickerBinding) {
holder.itemView.onClick { holder.itemView.onClick {
callBack.onPathClick(holder.layoutPosition) callBack.onPathClick(holder.layoutPosition)
} }
@ -65,6 +69,6 @@ class PathAdapter(context: Context, val callBack: CallBack) :
private const val ROOT_HINT = "SD" private const val ROOT_HINT = "SD"
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
val sdCardDirectory = Environment.getExternalStorageDirectory().absolutePath val sdCardDirectory: String = Environment.getExternalStorageDirectory().absolutePath
} }
} }

@ -47,10 +47,6 @@ class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
private var pagePosition = 0 private var pagePosition = 0
private val fragmentMap = hashMapOf<Int, Fragment>() private val fragmentMap = hashMapOf<Int, Fragment>()
override fun getViewBinding(): ActivityMainBinding {
return ActivityMainBinding.inflate(layoutInflater)
}
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
ATH.applyEdgeEffectColor(binding.viewPagerMain) ATH.applyEdgeEffectColor(binding.viewPagerMain)
ATH.applyBottomNavigationColor(binding.bottomNavigationView) ATH.applyBottomNavigationColor(binding.bottomNavigationView)

@ -2,8 +2,6 @@ package io.legado.app.ui.main.bookshelf.books
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.ViewGroup
import androidx.viewbinding.ViewBinding
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.constant.BookType import io.legado.app.constant.BookType
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
@ -16,10 +14,6 @@ import org.jetbrains.anko.sdk27.listeners.onLongClick
class BooksAdapterGrid(context: Context, private val callBack: CallBack) : class BooksAdapterGrid(context: Context, private val callBack: CallBack) :
BaseBooksAdapter<ItemBookshelfGridBinding>(context) { BaseBooksAdapter<ItemBookshelfGridBinding>(context) {
override fun getViewBinding(parent: ViewGroup, position: Int): ViewBinding {
return ItemBookshelfGridBinding.inflate(inflater, parent, false)
}
override fun convert( override fun convert(
holder: ItemViewHolder, holder: ItemViewHolder,
binding: ItemBookshelfGridBinding, binding: ItemBookshelfGridBinding,

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

@ -10,16 +10,16 @@ import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.ReplaceRule import io.legado.app.data.entities.ReplaceRule
import io.legado.app.databinding.ItemReplaceRuleBinding
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
import kotlinx.android.synthetic.main.item_replace_rule.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.* import java.util.*
class ReplaceRuleAdapter(context: Context, var callBack: CallBack) : class ReplaceRuleAdapter(context: Context, var callBack: CallBack) :
SimpleRecyclerAdapter<ReplaceRule>(context, R.layout.item_replace_rule), SimpleRecyclerAdapter<ReplaceRule, ItemReplaceRuleBinding>(context),
ItemTouchCallback.Callback { ItemTouchCallback.Callback {
private val selected = linkedSetOf<ReplaceRule>() private val selected = linkedSetOf<ReplaceRule>()
@ -54,53 +54,58 @@ class ReplaceRuleAdapter(context: Context, var callBack: CallBack) :
return selection return selection
} }
override fun convert(holder: ItemViewHolder, item: ReplaceRule, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
binding: ItemReplaceRuleBinding,
item: ReplaceRule,
payloads: MutableList<Any>
) {
with(binding) {
val bundle = payloads.getOrNull(0) as? Bundle val bundle = payloads.getOrNull(0) as? Bundle
if (bundle == null) { if (bundle == null) {
this.setBackgroundColor(context.backgroundColor) root.setBackgroundColor(context.backgroundColor)
if (item.group.isNullOrEmpty()) { if (item.group.isNullOrEmpty()) {
cb_name.text = item.name cbName.text = item.name
} else { } else {
cb_name.text = cbName.text =
String.format("%s (%s)", item.name, item.group) String.format("%s (%s)", item.name, item.group)
} }
swt_enabled.isChecked = item.isEnabled swtEnabled.isChecked = item.isEnabled
cb_name.isChecked = selected.contains(item) cbName.isChecked = selected.contains(item)
} else { } else {
bundle.keySet().map { bundle.keySet().map {
when (it) { when (it) {
"selected" -> cb_name.isChecked = selected.contains(item) "selected" -> cbName.isChecked = selected.contains(item)
"name", "group" -> "name", "group" ->
if (item.group.isNullOrEmpty()) { if (item.group.isNullOrEmpty()) {
cb_name.text = item.name cbName.text = item.name
} else { } else {
cb_name.text = cbName.text =
String.format("%s (%s)", item.name, item.group) String.format("%s (%s)", item.name, item.group)
} }
"enabled" -> swt_enabled.isChecked = item.isEnabled "enabled" -> swtEnabled.isChecked = item.isEnabled
} }
} }
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemReplaceRuleBinding) {
holder.itemView.apply { binding.apply {
swt_enabled.setOnCheckedChangeListener { _, isChecked -> swtEnabled.setOnCheckedChangeListener { _, isChecked ->
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
it.isEnabled = isChecked it.isEnabled = isChecked
callBack.update(it) callBack.update(it)
} }
} }
iv_edit.onClick { ivEdit.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callBack.edit(it) callBack.edit(it)
} }
} }
cb_name.onClick { cbName.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
if (cb_name.isChecked) { if (cbName.isChecked) {
selected.add(it) selected.add(it)
} else { } else {
selected.remove(it) selected.remove(it)
@ -108,8 +113,8 @@ class ReplaceRuleAdapter(context: Context, var callBack: CallBack) :
} }
callBack.upCountView() callBack.upCountView()
} }
iv_menu_more.onClick { ivMenuMore.onClick {
showMenu(iv_menu_more, holder.layoutPosition) showMenu(ivMenuMore, holder.layoutPosition)
} }
} }
} }

@ -20,8 +20,8 @@ import io.legado.app.ui.widget.KeyboardToolPop
import io.legado.app.ui.widget.dialog.TextDialog import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
import kotlinx.android.synthetic.main.activity_replace_edit.*
import org.jetbrains.anko.displayMetrics import org.jetbrains.anko.displayMetrics
import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.selector import org.jetbrains.anko.selector
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
import kotlin.math.abs import kotlin.math.abs
@ -58,17 +58,13 @@ class ReplaceEditActivity :
private var mSoftKeyboardTool: PopupWindow? = null private var mSoftKeyboardTool: PopupWindow? = null
private var mIsSoftKeyBoardShowing = false private var mIsSoftKeyBoardShowing = false
override fun getViewBinding(): ActivityReplaceEditBinding {
return ActivityReplaceEditBinding.inflate(layoutInflater)
}
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
mSoftKeyboardTool = KeyboardToolPop(this, AppConst.keyboardToolChars, this) mSoftKeyboardTool = KeyboardToolPop(this, AppConst.keyboardToolChars, this)
window.decorView.viewTreeObserver.addOnGlobalLayoutListener(this) window.decorView.viewTreeObserver.addOnGlobalLayoutListener(this)
viewModel.initData(intent) { viewModel.initData(intent) {
upReplaceView(it) upReplaceView(it)
} }
iv_help.onClick { binding.ivHelp.onClick {
showRegexHelp() showRegexHelp()
} }
} }
@ -95,23 +91,23 @@ class ReplaceEditActivity :
return true return true
} }
private fun upReplaceView(replaceRule: ReplaceRule) { private fun upReplaceView(replaceRule: ReplaceRule) = with(binding) {
et_name.setText(replaceRule.name) etName.setText(replaceRule.name)
et_group.setText(replaceRule.group) etGroup.setText(replaceRule.group)
et_replace_rule.setText(replaceRule.pattern) etReplaceRule.setText(replaceRule.pattern)
cb_use_regex.isChecked = replaceRule.isRegex cbUseRegex.isChecked = replaceRule.isRegex
et_replace_to.setText(replaceRule.replacement) etReplaceTo.setText(replaceRule.replacement)
et_scope.setText(replaceRule.scope) etScope.setText(replaceRule.scope)
} }
private fun getReplaceRule(): ReplaceRule { private fun getReplaceRule(): ReplaceRule = with(binding) {
val replaceRule: ReplaceRule = viewModel.replaceRule ?: ReplaceRule() val replaceRule: ReplaceRule = viewModel.replaceRule ?: ReplaceRule()
replaceRule.name = et_name.text.toString() replaceRule.name = etName.text.toString()
replaceRule.group = et_group.text.toString() replaceRule.group = etGroup.text.toString()
replaceRule.pattern = et_replace_rule.text.toString() replaceRule.pattern = etReplaceRule.text.toString()
replaceRule.isRegex = cb_use_regex.isChecked replaceRule.isRegex = cbUseRegex.isChecked
replaceRule.replacement = et_replace_to.text.toString() replaceRule.replacement = etReplaceTo.text.toString()
replaceRule.scope = et_scope.text.toString() replaceRule.scope = etScope.text.toString()
return replaceRule return replaceRule
} }
@ -158,7 +154,7 @@ class ReplaceEditActivity :
mSoftKeyboardTool?.let { mSoftKeyboardTool?.let {
if (it.isShowing) return if (it.isShowing) return
if (!isFinishing) { if (!isFinishing) {
it.showAtLocation(ll_content, Gravity.BOTTOM, 0, 0) it.showAtLocation(binding.llContent, Gravity.BOTTOM, 0, 0)
} }
} }
} }
@ -176,11 +172,11 @@ class ReplaceEditActivity :
val preShowing = mIsSoftKeyBoardShowing val preShowing = mIsSoftKeyBoardShowing
if (abs(keyboardHeight) > screenHeight / 5) { if (abs(keyboardHeight) > screenHeight / 5) {
mIsSoftKeyBoardShowing = true // 超过屏幕五分之一则表示弹出了输入法 mIsSoftKeyBoardShowing = true // 超过屏幕五分之一则表示弹出了输入法
root_view.setPadding(0, 0, 0, 100) binding.rootView.setPadding(0, 0, 0, 100)
showKeyboardTopPopupWindow() showKeyboardTopPopupWindow()
} else { } else {
mIsSoftKeyBoardShowing = false mIsSoftKeyBoardShowing = false
root_view.setPadding(0, 0, 0, 0) binding.rootView.setPadding(0, 0, 0, 0)
if (preShowing) { if (preShowing) {
closePopupWindow() closePopupWindow()
} }

@ -0,0 +1,16 @@
package io.legado.app.ui.rss.article
import android.content.Context
import androidx.viewbinding.ViewBinding
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.RssArticle
abstract class BaseRssArticlesAdapter<VB : ViewBinding>(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<RssArticle, VB>(context) {
interface CallBack {
val isGridLayout: Boolean
fun readRss(rssArticle: RssArticle)
}
}

@ -1,6 +1,5 @@
package io.legado.app.ui.rss.article package io.legado.app.ui.rss.article
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.DataSource
@ -9,26 +8,28 @@ import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssArticle
import io.legado.app.databinding.ItemRssArticleBinding
import io.legado.app.help.ImageLoader import io.legado.app.help.ImageLoader
import io.legado.app.utils.gone import io.legado.app.utils.gone
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_rss_article.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.textColorResource import org.jetbrains.anko.textColorResource
class RssArticlesAdapter(context: Context, callBack: CallBack) :
BaseRssArticlesAdapter<ItemRssArticleBinding>(context, callBack) {
class RssArticlesAdapter(context: Context, layoutId: Int, val callBack: CallBack) : override fun convert(
SimpleRecyclerAdapter<RssArticle>(context, layoutId) { holder: ItemViewHolder,
binding: ItemRssArticleBinding,
@SuppressLint("CheckResult") item: RssArticle,
override fun convert(holder: ItemViewHolder, item: RssArticle, payloads: MutableList<Any>) { payloads: MutableList<Any>
with(holder.itemView) { ) {
tv_title.text = item.title with(binding) {
tv_pub_date.text = item.pubDate tvTitle.text = item.title
tvPubDate.text = item.pubDate
if (item.image.isNullOrBlank() && !callBack.isGridLayout) { if (item.image.isNullOrBlank() && !callBack.isGridLayout) {
image_view.gone() imageView.gone()
} else { } else {
ImageLoader.load(context, item.image).apply { ImageLoader.load(context, item.image).apply {
if (callBack.isGridLayout) { if (callBack.isGridLayout) {
@ -41,7 +42,7 @@ class RssArticlesAdapter(context: Context, layoutId: Int, val callBack: CallBack
target: Target<Drawable>?, target: Target<Drawable>?,
isFirstResource: Boolean isFirstResource: Boolean
): Boolean { ): Boolean {
image_view.gone() imageView.gone()
return false return false
} }
@ -52,23 +53,23 @@ class RssArticlesAdapter(context: Context, layoutId: Int, val callBack: CallBack
dataSource: DataSource?, dataSource: DataSource?,
isFirstResource: Boolean isFirstResource: Boolean
): Boolean { ): Boolean {
image_view.visible() imageView.visible()
return false return false
} }
}) })
} }
}.into(image_view) }.into(imageView)
} }
if (item.read) { if (item.read) {
tv_title.textColorResource = R.color.tv_text_summary tvTitle.textColorResource = R.color.tv_text_summary
} else { } else {
tv_title.textColorResource = R.color.primaryText tvTitle.textColorResource = R.color.primaryText
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemRssArticleBinding) {
holder.itemView.onClick { holder.itemView.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callBack.readRss(it) callBack.readRss(it)
@ -76,8 +77,4 @@ class RssArticlesAdapter(context: Context, layoutId: Int, val callBack: CallBack
} }
} }
interface CallBack {
val isGridLayout: Boolean
fun readRss(rssArticle: RssArticle)
}
} }

@ -0,0 +1,80 @@
package io.legado.app.ui.rss.article
import android.content.Context
import android.graphics.drawable.Drawable
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.data.entities.RssArticle
import io.legado.app.databinding.ItemRssArticle1Binding
import io.legado.app.help.ImageLoader
import io.legado.app.utils.gone
import io.legado.app.utils.visible
import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.textColorResource
class RssArticlesAdapter1(context: Context, callBack: CallBack) :
BaseRssArticlesAdapter<ItemRssArticle1Binding>(context, callBack) {
override fun convert(
holder: ItemViewHolder,
binding: ItemRssArticle1Binding,
item: RssArticle,
payloads: MutableList<Any>
) {
with(binding) {
tvTitle.text = item.title
tvPubDate.text = item.pubDate
if (item.image.isNullOrBlank() && !callBack.isGridLayout) {
imageView.gone()
} else {
ImageLoader.load(context, item.image).apply {
if (callBack.isGridLayout) {
placeholder(R.drawable.image_rss_article)
} else {
addListener(object : RequestListener<Drawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean {
imageView.gone()
return false
}
override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
imageView.visible()
return false
}
})
}
}.into(imageView)
}
if (item.read) {
tvTitle.textColorResource = R.color.tv_text_summary
} else {
tvTitle.textColorResource = R.color.primaryText
}
}
}
override fun registerListener(holder: ItemViewHolder, binding: ItemRssArticle1Binding) {
holder.itemView.onClick {
getItem(holder.layoutPosition)?.let {
callBack.readRss(it)
}
}
}
}

@ -0,0 +1,80 @@
package io.legado.app.ui.rss.article
import android.content.Context
import android.graphics.drawable.Drawable
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.data.entities.RssArticle
import io.legado.app.databinding.ItemRssArticle2Binding
import io.legado.app.help.ImageLoader
import io.legado.app.utils.gone
import io.legado.app.utils.visible
import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.textColorResource
class RssArticlesAdapter2(context: Context, callBack: CallBack) :
BaseRssArticlesAdapter<ItemRssArticle2Binding>(context, callBack) {
override fun convert(
holder: ItemViewHolder,
binding: ItemRssArticle2Binding,
item: RssArticle,
payloads: MutableList<Any>
) {
with(binding) {
tvTitle.text = item.title
tvPubDate.text = item.pubDate
if (item.image.isNullOrBlank() && !callBack.isGridLayout) {
imageView.gone()
} else {
ImageLoader.load(context, item.image).apply {
if (callBack.isGridLayout) {
placeholder(R.drawable.image_rss_article)
} else {
addListener(object : RequestListener<Drawable> {
override fun onLoadFailed(
e: GlideException?,
model: Any?,
target: Target<Drawable>?,
isFirstResource: Boolean
): Boolean {
imageView.gone()
return false
}
override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
imageView.visible()
return false
}
})
}
}.into(imageView)
}
if (item.read) {
tvTitle.textColorResource = R.color.tv_text_summary
} else {
tvTitle.textColorResource = R.color.primaryText
}
}
}
override fun registerListener(holder: ItemViewHolder, binding: ItemRssArticle2Binding) {
holder.itemView.onClick {
getItem(holder.layoutPosition)?.let {
callBack.readRss(it)
}
}
}
}

@ -10,6 +10,8 @@ import io.legado.app.App
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseFragment import io.legado.app.base.VMBaseFragment
import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssArticle
import io.legado.app.databinding.FragmentRssArticlesBinding
import io.legado.app.databinding.ViewLoadMoreBinding
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.ui.rss.read.ReadRssActivity import io.legado.app.ui.rss.read.ReadRssActivity
import io.legado.app.ui.widget.recycler.LoadMoreView import io.legado.app.ui.widget.recycler.LoadMoreView
@ -17,12 +19,10 @@ import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
import io.legado.app.utils.getViewModelOfActivity import io.legado.app.utils.getViewModelOfActivity
import io.legado.app.utils.startActivity import io.legado.app.utils.startActivity
import kotlinx.android.synthetic.main.fragment_rss_articles.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.view_load_more.view.*
import kotlinx.android.synthetic.main.view_refresh_recycler.*
class RssArticlesFragment : VMBaseFragment<RssArticlesViewModel>(R.layout.fragment_rss_articles), class RssArticlesFragment : VMBaseFragment<RssArticlesViewModel>(R.layout.fragment_rss_articles),
RssArticlesAdapter.CallBack { BaseRssArticlesAdapter.CallBack {
companion object { companion object {
fun create(sortName: String, sortUrl: String): RssArticlesFragment { fun create(sortName: String, sortUrl: String): RssArticlesFragment {
@ -35,11 +35,12 @@ class RssArticlesFragment : VMBaseFragment<RssArticlesViewModel>(R.layout.fragme
} }
} }
private val binding by viewBinding(FragmentRssArticlesBinding::bind)
private val activityViewModel: RssSortViewModel private val activityViewModel: RssSortViewModel
get() = getViewModelOfActivity(RssSortViewModel::class.java) get() = getViewModelOfActivity(RssSortViewModel::class.java)
override val viewModel: RssArticlesViewModel override val viewModel: RssArticlesViewModel
get() = getViewModel(RssArticlesViewModel::class.java) get() = getViewModel(RssArticlesViewModel::class.java)
lateinit var adapter: RssArticlesAdapter lateinit var adapter: BaseRssArticlesAdapter<*>
private lateinit var loadMoreView: LoadMoreView private lateinit var loadMoreView: LoadMoreView
private var rssArticlesData: LiveData<List<RssArticle>>? = null private var rssArticlesData: LiveData<List<RssArticle>>? = null
override val isGridLayout: Boolean override val isGridLayout: Boolean
@ -48,31 +49,36 @@ class RssArticlesFragment : VMBaseFragment<RssArticlesViewModel>(R.layout.fragme
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
viewModel.init(arguments) viewModel.init(arguments)
initView() initView()
refresh_recycler_view.startLoading() binding.refreshRecyclerView.startLoading()
initView() initView()
initData() initData()
} }
private fun initView() { private fun initView() = with(binding) {
ATH.applyEdgeEffectColor(recycler_view) ATH.applyEdgeEffectColor(refreshRecyclerView.recyclerView)
recycler_view.layoutManager = if (activityViewModel.isGridLayout) { refreshRecyclerView.recyclerView.layoutManager = if (activityViewModel.isGridLayout) {
recycler_view.setPadding(8, 0, 8, 0) refreshRecyclerView.recyclerView.setPadding(8, 0, 8, 0)
GridLayoutManager(requireContext(), 2) GridLayoutManager(requireContext(), 2)
} else { } else {
recycler_view.addItemDecoration(VerticalDivider(requireContext())) refreshRecyclerView.recyclerView.addItemDecoration(VerticalDivider(requireContext()))
LinearLayoutManager(requireContext()) LinearLayoutManager(requireContext())
} }
adapter = RssArticlesAdapter(requireContext(), activityViewModel.layoutId, this) adapter = when (activityViewModel.rssSource?.articleStyle) {
recycler_view.adapter = adapter 1 -> RssArticlesAdapter1(requireContext(), this@RssArticlesFragment)
2 -> RssArticlesAdapter2(requireContext(), this@RssArticlesFragment)
else -> RssArticlesAdapter(requireContext(), this@RssArticlesFragment)
}
refreshRecyclerView.recyclerView.adapter = adapter
loadMoreView = LoadMoreView(requireContext()) loadMoreView = LoadMoreView(requireContext())
adapter.addFooterView(loadMoreView) adapter.addFooterView(ViewLoadMoreBinding.bind(loadMoreView))
refresh_recycler_view.onRefreshStart = { refreshRecyclerView.onRefreshStart = {
activityViewModel.rssSource?.let { activityViewModel.rssSource?.let {
viewModel.loadContent(it) viewModel.loadContent(it)
} }
} }
recycler_view.addOnScrollListener(object : RecyclerView.OnScrollListener() { refreshRecyclerView.recyclerView.addOnScrollListener(object :
RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy) super.onScrolled(recyclerView, dx, dy)
if (!recyclerView.canScrollVertically(1)) { if (!recyclerView.canScrollVertically(1)) {
@ -95,7 +101,7 @@ class RssArticlesFragment : VMBaseFragment<RssArticlesViewModel>(R.layout.fragme
private fun scrollToBottom() { private fun scrollToBottom() {
if (viewModel.isLoading) return if (viewModel.isLoading) return
if (loadMoreView.hasMore && adapter.getActualItemCount() > 0) { if (loadMoreView.hasMore && adapter.getActualItemCount() > 0) {
loadMoreView.rotate_loading.show() loadMoreView.startLoad()
activityViewModel.rssSource?.let { activityViewModel.rssSource?.let {
viewModel.loadMore(it) viewModel.loadMore(it)
} }
@ -104,7 +110,7 @@ class RssArticlesFragment : VMBaseFragment<RssArticlesViewModel>(R.layout.fragme
override fun observeLiveBus() { override fun observeLiveBus() {
viewModel.loadFinally.observe(viewLifecycleOwner) { viewModel.loadFinally.observe(viewLifecycleOwner) {
refresh_recycler_view.stopLoading() binding.refreshRecyclerView.stopLoading()
if (it) { if (it) {
loadMoreView.startLoad() loadMoreView.startLoad()
} else { } else {

@ -4,7 +4,6 @@ import android.app.Application
import android.content.Intent import android.content.Intent
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import io.legado.app.App import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssArticle
import io.legado.app.data.entities.RssReadRecord import io.legado.app.data.entities.RssReadRecord
@ -17,12 +16,6 @@ class RssSortViewModel(application: Application) : BaseViewModel(application) {
val titleLiveData = MutableLiveData<String>() val titleLiveData = MutableLiveData<String>()
var order = System.currentTimeMillis() var order = System.currentTimeMillis()
val isGridLayout get() = rssSource?.articleStyle == 2 val isGridLayout get() = rssSource?.articleStyle == 2
val layoutId
get() = when (rssSource?.articleStyle) {
1 -> R.layout.item_rss_article_1
2 -> R.layout.item_rss_article_2
else -> R.layout.item_rss_article
}
fun initData(intent: Intent, finally: () -> Unit) { fun initData(intent: Intent, finally: () -> Unit) {
execute { execute {

@ -6,25 +6,29 @@ import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.RssStar import io.legado.app.data.entities.RssStar
import io.legado.app.databinding.ItemRssArticleBinding
import io.legado.app.help.ImageLoader import io.legado.app.help.ImageLoader
import io.legado.app.utils.gone import io.legado.app.utils.gone
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_rss_article.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class RssFavoritesAdapter(context: Context, val callBack: CallBack) : class RssFavoritesAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<RssStar>(context, R.layout.item_rss_article) { SimpleRecyclerAdapter<RssStar, ItemRssArticleBinding>(context) {
override fun convert(holder: ItemViewHolder, item: RssStar, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
tv_title.text = item.title binding: ItemRssArticleBinding,
tv_pub_date.text = item.pubDate item: RssStar,
payloads: MutableList<Any>
) {
with(binding) {
tvTitle.text = item.title
tvPubDate.text = item.pubDate
if (item.image.isNullOrBlank()) { if (item.image.isNullOrBlank()) {
image_view.gone() imageView.gone()
} else { } else {
ImageLoader.load(context, item.image) ImageLoader.load(context, item.image)
.addListener(object : RequestListener<Drawable> { .addListener(object : RequestListener<Drawable> {
@ -34,7 +38,7 @@ class RssFavoritesAdapter(context: Context, val callBack: CallBack) :
target: Target<Drawable>?, target: Target<Drawable>?,
isFirstResource: Boolean isFirstResource: Boolean
): Boolean { ): Boolean {
image_view.gone() imageView.gone()
return false return false
} }
@ -45,17 +49,17 @@ class RssFavoritesAdapter(context: Context, val callBack: CallBack) :
dataSource: DataSource?, dataSource: DataSource?,
isFirstResource: Boolean isFirstResource: Boolean
): Boolean { ): Boolean {
image_view.visible() imageView.visible()
return false return false
} }
}) })
.into(image_view) .into(imageView)
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemRssArticleBinding) {
holder.itemView.onClick { holder.itemView.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callBack.readRss(it) callBack.readRss(it)

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

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

@ -7,7 +7,6 @@ import android.view.LayoutInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.EditText
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App import io.legado.app.App
@ -16,19 +15,21 @@ import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.AppPattern import io.legado.app.constant.AppPattern
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemGroupManageBinding
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.dialog_recycler_view.*
import kotlinx.android.synthetic.main.item_group_manage.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener { class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
private lateinit var viewModel: RssSourceViewModel private lateinit var viewModel: RssSourceViewModel
private lateinit var adapter: GroupAdapter private lateinit var adapter: GroupAdapter
private val binding by viewBinding(DialogRecyclerViewBinding::bind)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
@ -45,19 +46,19 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
return inflater.inflate(R.layout.dialog_recycler_view, container) return inflater.inflate(R.layout.dialog_recycler_view, container)
} }
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) = with(binding) {
tool_bar.setBackgroundColor(primaryColor) toolBar.setBackgroundColor(primaryColor)
tool_bar.title = getString(R.string.group_manage) toolBar.title = getString(R.string.group_manage)
tool_bar.inflateMenu(R.menu.group_manage) toolBar.inflateMenu(R.menu.group_manage)
tool_bar.menu.applyTint(requireContext()) toolBar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this) toolBar.setOnMenuItemClickListener(this@GroupManageDialog)
adapter = GroupAdapter(requireContext()) adapter = GroupAdapter(requireContext())
recycler_view.layoutManager = LinearLayoutManager(requireContext()) recyclerView.layoutManager = LinearLayoutManager(requireContext())
recycler_view.addItemDecoration(VerticalDivider(requireContext())) recyclerView.addItemDecoration(VerticalDivider(requireContext()))
recycler_view.adapter = adapter recyclerView.adapter = adapter
tv_ok.setTextColor(requireContext().accentColor) tvOk.setTextColor(requireContext().accentColor)
tv_ok.visible() tvOk.visible()
tv_ok.onClick { dismiss() } tvOk.onClick { dismiss() }
App.db.rssSourceDao().liveGroup().observe(viewLifecycleOwner, { App.db.rssSourceDao().liveGroup().observe(viewLifecycleOwner, {
val groups = linkedSetOf<String>() val groups = linkedSetOf<String>()
it.map { group -> it.map { group ->
@ -77,16 +78,14 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun addGroup() { private fun addGroup() {
alert(title = getString(R.string.add_group)) { alert(title = getString(R.string.add_group)) {
var editText: EditText? = null val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
customView { customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { alertBinding.apply {
editText = edit_view.apply { editView.setHint(R.string.group_name)
hint = "分组名称" }.root
}
}
} }
yesButton { yesButton {
editText?.text?.toString()?.let { alertBinding.editView.text?.toString()?.let {
if (it.isNotBlank()) { if (it.isNotBlank()) {
viewModel.addGroup(it) viewModel.addGroup(it)
} }
@ -99,40 +98,43 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
@SuppressLint("InflateParams") @SuppressLint("InflateParams")
private fun editGroup(group: String) { private fun editGroup(group: String) {
alert(title = getString(R.string.group_edit)) { alert(title = getString(R.string.group_edit)) {
var editText: EditText? = null val alertBinding = DialogEditTextBinding.inflate(layoutInflater)
customView { customView {
layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { alertBinding.apply {
editText = edit_view.apply { editView.setHint(R.string.group_name)
hint = "分组名称" editView.setText(group)
setText(group) }.root
}
}
} }
yesButton { yesButton {
viewModel.upGroup(group, editText?.text?.toString()) viewModel.upGroup(group, alertBinding.editView.text?.toString())
} }
noButton() noButton()
}.show().requestInputMethod() }.show().requestInputMethod()
} }
private inner class GroupAdapter(context: Context) : private inner class GroupAdapter(context: Context) :
SimpleRecyclerAdapter<String>(context, R.layout.item_group_manage) { SimpleRecyclerAdapter<String, ItemGroupManageBinding>(context) {
override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
tv_group.text = item binding: ItemGroupManageBinding,
item: String,
payloads: MutableList<Any>
) {
with(binding) {
tvGroup.text = item
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemGroupManageBinding) {
holder.itemView.apply { binding.apply {
tv_edit.onClick { tvEdit.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
editGroup(it) editGroup(it)
} }
} }
tv_del.onClick { tvDel.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
viewModel.delGroup(it) viewModel.delGroup(it)
} }

@ -10,15 +10,15 @@ import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssSource
import io.legado.app.databinding.ItemRssSourceBinding
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
import kotlinx.android.synthetic.main.item_rss_source.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.* import java.util.*
class RssSourceAdapter(context: Context, val callBack: CallBack) : class RssSourceAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<RssSource>(context, R.layout.item_rss_source), SimpleRecyclerAdapter<RssSource, ItemRssSourceBinding>(context),
ItemTouchCallback.Callback { ItemTouchCallback.Callback {
private val selected = linkedSetOf<RssSource>() private val selected = linkedSetOf<RssSource>()
@ -53,40 +53,45 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
return selection.sortedBy { it.customOrder } return selection.sortedBy { it.customOrder }
} }
override fun convert(holder: ItemViewHolder, item: RssSource, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
binding: ItemRssSourceBinding,
item: RssSource,
payloads: MutableList<Any>
) {
with(binding) {
val bundle = payloads.getOrNull(0) as? Bundle val bundle = payloads.getOrNull(0) as? Bundle
if (bundle == null) { if (bundle == null) {
this.setBackgroundColor(context.backgroundColor) root.setBackgroundColor(context.backgroundColor)
if (item.sourceGroup.isNullOrEmpty()) { if (item.sourceGroup.isNullOrEmpty()) {
cb_source.text = item.sourceName cbSource.text = item.sourceName
} else { } else {
cb_source.text = cbSource.text =
String.format("%s (%s)", item.sourceName, item.sourceGroup) String.format("%s (%s)", item.sourceName, item.sourceGroup)
} }
swt_enabled.isChecked = item.enabled swtEnabled.isChecked = item.enabled
cb_source.isChecked = selected.contains(item) cbSource.isChecked = selected.contains(item)
} else { } else {
bundle.keySet().map { bundle.keySet().map {
when (it) { when (it) {
"name", "group" -> "name", "group" ->
if (item.sourceGroup.isNullOrEmpty()) { if (item.sourceGroup.isNullOrEmpty()) {
cb_source.text = item.sourceName cbSource.text = item.sourceName
} else { } else {
cb_source.text = cbSource.text =
String.format("%s (%s)", item.sourceName, item.sourceGroup) String.format("%s (%s)", item.sourceName, item.sourceGroup)
} }
"selected" -> cb_source.isChecked = selected.contains(item) "selected" -> cbSource.isChecked = selected.contains(item)
"enabled" -> swt_enabled.isChecked = item.enabled "enabled" -> cbSource.isChecked = item.enabled
} }
} }
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemRssSourceBinding) {
holder.itemView.apply { binding.apply {
swt_enabled.setOnCheckedChangeListener { view, checked -> swtEnabled.setOnCheckedChangeListener { view, checked ->
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
if (view.isPressed) { if (view.isPressed) {
it.enabled = checked it.enabled = checked
@ -94,7 +99,7 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
} }
} }
} }
cb_source.setOnCheckedChangeListener { view, checked -> cbSource.setOnCheckedChangeListener { view, checked ->
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
if (view.isPressed) { if (view.isPressed) {
if (checked) { if (checked) {
@ -106,13 +111,13 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
} }
} }
} }
iv_edit.onClick { ivEdit.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callBack.edit(it) callBack.edit(it)
} }
} }
iv_menu_more.onClick { ivMenuMore.onClick {
showMenu(iv_menu_more, holder.layoutPosition) showMenu(ivMenuMore, holder.layoutPosition)
} }
} }
} }

@ -1,17 +1,15 @@
package io.legado.app.ui.widget package io.legado.app.ui.widget
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.PopupWindow import android.widget.PopupWindow
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import kotlinx.android.synthetic.main.item_fillet_text.view.* import io.legado.app.databinding.ItemFilletTextBinding
import kotlinx.android.synthetic.main.popup_keyboard_tool.view.* import io.legado.app.databinding.PopupKeyboardToolBinding
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
@ -21,9 +19,10 @@ class KeyboardToolPop(
val callBack: CallBack? val callBack: CallBack?
) : PopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) { ) : PopupWindow(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) {
private val binding = PopupKeyboardToolBinding.inflate(LayoutInflater.from(context))
init { init {
@SuppressLint("InflateParams") contentView = binding.root
contentView = LayoutInflater.from(context).inflate(R.layout.popup_keyboard_tool, null)
isTouchable = true isTouchable = true
isOutsideTouchable = false isOutsideTouchable = false
@ -34,21 +33,27 @@ class KeyboardToolPop(
private fun initRecyclerView() = with(contentView) { private fun initRecyclerView() = with(contentView) {
val adapter = Adapter(context) val adapter = Adapter(context)
recycler_view.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false) binding.recyclerView.layoutManager =
recycler_view.adapter = adapter LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
binding.recyclerView.adapter = adapter
adapter.setItems(chars) adapter.setItems(chars)
} }
inner class Adapter(context: Context) : inner class Adapter(context: Context) :
SimpleRecyclerAdapter<String>(context, R.layout.item_fillet_text) { SimpleRecyclerAdapter<String, ItemFilletTextBinding>(context) {
override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
text_view.text = item binding: ItemFilletTextBinding,
item: String,
payloads: MutableList<Any>
) {
with(binding) {
textView.text = item
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemFilletTextBinding) {
holder.itemView.apply { holder.itemView.apply {
onClick { onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {

@ -2,18 +2,18 @@ package io.legado.app.ui.widget
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.View
import android.widget.FrameLayout import android.widget.FrameLayout
import androidx.annotation.MenuRes import androidx.annotation.MenuRes
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.PopupMenu
import io.legado.app.R import io.legado.app.R
import io.legado.app.databinding.ViewSelectActionBarBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.lib.theme.* import io.legado.app.lib.theme.*
import io.legado.app.utils.ColorUtils import io.legado.app.utils.ColorUtils
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.view_select_action_bar.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
@Suppress("unused") @Suppress("unused")
@ -23,42 +23,43 @@ class SelectActionBar @JvmOverloads constructor(
) : FrameLayout(context, attrs) { ) : FrameLayout(context, attrs) {
private var callBack: CallBack? = null private var callBack: CallBack? = null
private var selMenu: PopupMenu? = null private var selMenu: PopupMenu? = null
private val binding =
ViewSelectActionBarBinding.inflate(LayoutInflater.from(context), this, true)
init { init {
setBackgroundColor(context.bottomBackground) setBackgroundColor(context.bottomBackground)
elevation = elevation =
if (AppConfig.elevation < 0) context.elevation else AppConfig.elevation.toFloat() if (AppConfig.elevation < 0) context.elevation else AppConfig.elevation.toFloat()
View.inflate(context, R.layout.view_select_action_bar, this)
val textIsDark = ColorUtils.isColorLight(context.bottomBackground) val textIsDark = ColorUtils.isColorLight(context.bottomBackground)
val primaryTextColor = context.getPrimaryTextColor(textIsDark) val primaryTextColor = context.getPrimaryTextColor(textIsDark)
val secondaryTextColor = context.getSecondaryTextColor(textIsDark) val secondaryTextColor = context.getSecondaryTextColor(textIsDark)
cb_selected_all.setTextColor(primaryTextColor) binding.cbSelectedAll.setTextColor(primaryTextColor)
TintHelper.setTint(cb_selected_all, context.accentColor, !textIsDark) TintHelper.setTint(binding.cbSelectedAll, context.accentColor, !textIsDark)
iv_menu_more.setColorFilter(secondaryTextColor) binding.ivMenuMore.setColorFilter(secondaryTextColor)
cb_selected_all.setOnCheckedChangeListener { buttonView, isChecked -> binding.cbSelectedAll.setOnCheckedChangeListener { buttonView, isChecked ->
if (buttonView.isPressed) { if (buttonView.isPressed) {
callBack?.selectAll(isChecked) callBack?.selectAll(isChecked)
} }
} }
btn_revert_selection.onClick { callBack?.revertSelection() } binding.btnRevertSelection.onClick { callBack?.revertSelection() }
btn_select_action_main.onClick { callBack?.onClickMainAction() } binding.btnSelectActionMain.onClick { callBack?.onClickMainAction() }
iv_menu_more.onClick { selMenu?.show() } binding.ivMenuMore.onClick { selMenu?.show() }
} }
fun setMainActionText(text: String) { fun setMainActionText(text: String) = with(binding) {
btn_select_action_main.text = text btnSelectActionMain.text = text
btn_select_action_main.visible() btnSelectActionMain.visible()
} }
fun setMainActionText(@StringRes id: Int) { fun setMainActionText(@StringRes id: Int) = with(binding) {
btn_select_action_main.setText(id) btnSelectActionMain.setText(id)
btn_select_action_main.visible() btnSelectActionMain.visible()
} }
fun inflateMenu(@MenuRes resId: Int): Menu? { fun inflateMenu(@MenuRes resId: Int): Menu? {
selMenu = PopupMenu(context, iv_menu_more) selMenu = PopupMenu(context, binding.ivMenuMore)
selMenu?.inflate(resId) selMenu?.inflate(resId)
iv_menu_more.visible() binding.ivMenuMore.visible()
return selMenu?.menu return selMenu?.menu
} }
@ -70,22 +71,22 @@ class SelectActionBar @JvmOverloads constructor(
selMenu?.setOnMenuItemClickListener(listener) selMenu?.setOnMenuItemClickListener(listener)
} }
fun upCountView(selectCount: Int, allCount: Int) { fun upCountView(selectCount: Int, allCount: Int) = with(binding) {
if (selectCount == 0) { if (selectCount == 0) {
cb_selected_all.isChecked = false cbSelectedAll.isChecked = false
} else { } else {
cb_selected_all.isChecked = selectCount >= allCount cbSelectedAll.isChecked = selectCount >= allCount
} }
//重置全选的文字 //重置全选的文字
if (cb_selected_all.isChecked) { if (cbSelectedAll.isChecked) {
cb_selected_all.text = context.getString( cbSelectedAll.text = context.getString(
R.string.select_cancel_count, R.string.select_cancel_count,
selectCount, selectCount,
allCount allCount
) )
} else { } else {
cb_selected_all.text = context.getString( cbSelectedAll.text = context.getString(
R.string.select_all_count, R.string.select_all_count,
selectCount, selectCount,
allCount allCount
@ -94,11 +95,11 @@ class SelectActionBar @JvmOverloads constructor(
setMenuClickable(selectCount > 0) setMenuClickable(selectCount > 0)
} }
private fun setMenuClickable(isClickable: Boolean) { private fun setMenuClickable(isClickable: Boolean) = with(binding) {
btn_revert_selection.isEnabled = isClickable btnRevertSelection.isEnabled = isClickable
btn_revert_selection.isClickable = isClickable btnRevertSelection.isClickable = isClickable
btn_select_action_main.isEnabled = isClickable btnSelectActionMain.isEnabled = isClickable
btn_select_action_main.isClickable = isClickable btnSelectActionMain.isClickable = isClickable
} }
interface CallBack { interface CallBack {

@ -7,9 +7,10 @@ import android.view.ViewGroup
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.databinding.DialogPhotoViewBinding
import io.legado.app.service.help.ReadBook import io.legado.app.service.help.ReadBook
import io.legado.app.ui.book.read.page.provider.ImageProvider import io.legado.app.ui.book.read.page.provider.ImageProvider
import kotlinx.android.synthetic.main.dialog_photo_view.* import io.legado.app.utils.viewbindingdelegate.viewBinding
class PhotoDialog : BaseDialogFragment() { class PhotoDialog : BaseDialogFragment() {
@ -31,6 +32,8 @@ class PhotoDialog : BaseDialogFragment() {
} }
private val binding by viewBinding(DialogPhotoViewBinding::bind)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
dialog?.window?.setLayout( dialog?.window?.setLayout(
@ -57,7 +60,7 @@ class PhotoDialog : BaseDialogFragment() {
ImageProvider.getImage(book, chapterIndex, src) ImageProvider.getImage(book, chapterIndex, src)
}.onSuccess { bitmap -> }.onSuccess { bitmap ->
if (bitmap != null) { if (bitmap != null) {
photo_view.setImageBitmap(bitmap) binding.photoView.setImageBitmap(bitmap)
} }
} }
} }

@ -7,10 +7,11 @@ import android.view.ViewGroup
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.databinding.DialogTextViewBinding
import io.legado.app.utils.getSize import io.legado.app.utils.getSize
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.noties.markwon.Markwon import io.noties.markwon.Markwon
import io.noties.markwon.image.glide.GlideImagesPlugin import io.noties.markwon.image.glide.GlideImagesPlugin
import kotlinx.android.synthetic.main.dialog_text_view.*
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -40,8 +41,8 @@ class TextDialog : BaseDialogFragment() {
} }
private val binding by viewBinding(DialogTextViewBinding::bind)
private var time = 0L private var time = 0L
private var autoClose: Boolean = false private var autoClose: Boolean = false
override fun onStart() { override fun onStart() {
@ -62,23 +63,23 @@ class TextDialog : BaseDialogFragment() {
arguments?.let { arguments?.let {
val content = it.getString("content") ?: "" val content = it.getString("content") ?: ""
when (it.getInt("mode")) { when (it.getInt("mode")) {
MD -> text_view.post { MD -> binding.textView.post {
Markwon.builder(requireContext()) Markwon.builder(requireContext())
.usePlugin(GlideImagesPlugin.create(requireContext())) .usePlugin(GlideImagesPlugin.create(requireContext()))
.build() .build()
.setMarkdown(text_view, content) .setMarkdown(binding.textView, content)
} }
else -> text_view.text = content else -> binding.textView.text = content
} }
time = it.getLong("time", 0L) time = it.getLong("time", 0L)
} }
if (time > 0) { if (time > 0) {
badge_view.setBadgeCount((time / 1000).toInt()) binding.badgeView.setBadgeCount((time / 1000).toInt())
launch { launch {
while (time > 0) { while (time > 0) {
delay(1000) delay(1000)
time -= 1000 time -= 1000
badge_view.setBadgeCount((time / 1000).toInt()) binding.badgeView.setBadgeCount((time / 1000).toInt())
if (time <= 0) { if (time <= 0) {
view.post { view.post {
dialog?.setCancelable(true) dialog?.setCancelable(true)

@ -11,9 +11,10 @@ import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemLogBinding
import io.legado.app.utils.getSize import io.legado.app.utils.getSize
import kotlinx.android.synthetic.main.dialog_recycler_view.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.item_log.view.*
class TextListDialog : BaseDialogFragment() { class TextListDialog : BaseDialogFragment() {
@ -28,8 +29,9 @@ class TextListDialog : BaseDialogFragment() {
} }
} }
private val binding by viewBinding(DialogRecyclerViewBinding::bind)
lateinit var adapter: TextAdapter lateinit var adapter: TextAdapter
var values: ArrayList<String>? = null private var values: ArrayList<String>? = null
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
@ -45,38 +47,44 @@ class TextListDialog : BaseDialogFragment() {
return inflater.inflate(R.layout.dialog_recycler_view, container) return inflater.inflate(R.layout.dialog_recycler_view, container)
} }
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) = with(binding) {
arguments?.let { arguments?.let {
tool_bar.title = it.getString("title") toolBar.title = it.getString("title")
values = it.getStringArrayList("values") values = it.getStringArrayList("values")
} }
recycler_view.layoutManager = LinearLayoutManager(requireContext()) recyclerView.layoutManager = LinearLayoutManager(requireContext())
adapter = TextAdapter(requireContext()) adapter = TextAdapter(requireContext())
recycler_view.adapter = adapter recyclerView.adapter = adapter
adapter.setItems(values) adapter.setItems(values)
} }
class TextAdapter(context: Context) : class TextAdapter(context: Context) :
SimpleRecyclerAdapter<String>(context, R.layout.item_log) { SimpleRecyclerAdapter<String, ItemLogBinding>(context) {
override fun convert(holder: ItemViewHolder, item: String, payloads: MutableList<Any>) {
holder.itemView.apply { override fun convert(
if (text_view.getTag(R.id.tag1) == null) { holder: ItemViewHolder,
binding: ItemLogBinding,
item: String,
payloads: MutableList<Any>
) {
binding.apply {
if (textView.getTag(R.id.tag1) == null) {
val listener = object : View.OnAttachStateChangeListener { val listener = object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View) { override fun onViewAttachedToWindow(v: View) {
text_view.isCursorVisible = false textView.isCursorVisible = false
text_view.isCursorVisible = true textView.isCursorVisible = true
} }
override fun onViewDetachedFromWindow(v: View) {} override fun onViewDetachedFromWindow(v: View) {}
} }
text_view.addOnAttachStateChangeListener(listener) textView.addOnAttachStateChangeListener(listener)
text_view.setTag(R.id.tag1, listener) textView.setTag(R.id.tag1, listener)
} }
text_view.text = item textView.text = item
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemLogBinding) {
//nothing //nothing
} }
} }

@ -4,13 +4,13 @@ import android.content.Context
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import android.view.ViewStub
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ProgressBar import android.widget.ProgressBar
import androidx.appcompat.widget.AppCompatButton import androidx.appcompat.widget.AppCompatButton
import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatImageView
import androidx.appcompat.widget.AppCompatTextView import androidx.appcompat.widget.AppCompatTextView
import io.legado.app.R import io.legado.app.R
import kotlinx.android.synthetic.main.view_dynamic.view.*
@Suppress("unused") @Suppress("unused")
class DynamicFrameLayout @JvmOverloads constructor( class DynamicFrameLayout @JvmOverloads constructor(
@ -150,7 +150,7 @@ class DynamicFrameLayout @JvmOverloads constructor(
private fun ensureErrorView() { private fun ensureErrorView() {
if (errorView == null) { if (errorView == null) {
errorView = errorViewStub.inflate() errorView = findViewById<ViewStub>(R.id.error_view_stub).inflate()
errorImage = errorView?.findViewById(R.id.iv_error_image) errorImage = errorView?.findViewById(R.id.iv_error_image)
errorTextView = errorView?.findViewById(R.id.tv_error_message) errorTextView = errorView?.findViewById(R.id.tv_error_message)
actionBtn = errorView?.findViewById(R.id.btn_error_retry) actionBtn = errorView?.findViewById(R.id.btn_error_retry)
@ -166,7 +166,7 @@ class DynamicFrameLayout @JvmOverloads constructor(
private fun ensureProgressView() { private fun ensureProgressView() {
if (progressView == null) { if (progressView == null) {
progressView = progressViewStub.inflate() progressView = findViewById<ViewStub>(R.id.progress_view_stub).inflate()
progressBar = progressView?.findViewById(R.id.loading_progress) progressBar = progressView?.findViewById(R.id.loading_progress)
} }
} }

@ -3,23 +3,27 @@ package io.legado.app.ui.widget.font
import android.content.Context import android.content.Context
import android.graphics.Typeface import android.graphics.Typeface
import android.os.Build import android.os.Build
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.databinding.ItemFontBinding
import io.legado.app.utils.DocItem import io.legado.app.utils.DocItem
import io.legado.app.utils.RealPathUtil import io.legado.app.utils.RealPathUtil
import io.legado.app.utils.invisible import io.legado.app.utils.invisible
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_font.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
import java.io.File import java.io.File
class FontAdapter(context: Context, val callBack: CallBack) : class FontAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<DocItem>(context, R.layout.item_font) { SimpleRecyclerAdapter<DocItem, ItemFontBinding>(context) {
override fun convert(holder: ItemViewHolder, item: DocItem, payloads: MutableList<Any>) { override fun convert(
with(holder.itemView) { holder: ItemViewHolder,
binding: ItemFontBinding,
item: DocItem,
payloads: MutableList<Any>
) {
with(binding) {
try { try {
val typeface: Typeface? = if (item.isContentPath) { val typeface: Typeface? = if (item.isContentPath) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@ -34,22 +38,22 @@ class FontAdapter(context: Context, val callBack: CallBack) :
} else { } else {
Typeface.createFromFile(item.uri.toString()) Typeface.createFromFile(item.uri.toString())
} }
tv_font.typeface = typeface tvFont.typeface = typeface
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
context.toast("Read ${item.name} Error: ${e.localizedMessage}") context.toast("Read ${item.name} Error: ${e.localizedMessage}")
} }
tv_font.text = item.name tvFont.text = item.name
this.onClick { callBack.onClick(item) } root.onClick { callBack.onClick(item) }
if (item.name == callBack.curFilePath.substringAfterLast(File.separator)) { if (item.name == callBack.curFilePath.substringAfterLast(File.separator)) {
iv_checked.visible() ivChecked.visible()
} else { } else {
iv_checked.invisible() ivChecked.invisible()
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(holder: ItemViewHolder, binding: ItemFontBinding) {
holder.itemView.onClick { holder.itemView.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
callBack.onClick(it) callBack.onClick(it)

@ -15,6 +15,7 @@ import io.legado.app.App
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.databinding.DialogFontSelectBinding
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.permission.Permissions import io.legado.app.help.permission.Permissions
import io.legado.app.help.permission.PermissionsCompat import io.legado.app.help.permission.PermissionsCompat
@ -23,7 +24,7 @@ import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.filepicker.FilePicker import io.legado.app.ui.filepicker.FilePicker
import io.legado.app.ui.filepicker.FilePickerDialog import io.legado.app.ui.filepicker.FilePickerDialog
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_font_select.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.io.File import java.io.File
@ -40,6 +41,7 @@ class FontSelectDialog : BaseDialogFragment(),
FileUtils.createFolderIfNotExist(App.INSTANCE.filesDir, "Fonts") FileUtils.createFolderIfNotExist(App.INSTANCE.filesDir, "Fonts")
} }
private var adapter: FontAdapter? = null private var adapter: FontAdapter? = null
private val binding by viewBinding(DialogFontSelectBinding::bind)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
@ -56,14 +58,14 @@ class FontSelectDialog : BaseDialogFragment(),
} }
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
tool_bar.setTitle(R.string.select_font) binding.toolBar.setTitle(R.string.select_font)
tool_bar.inflateMenu(R.menu.font_select) binding.toolBar.inflateMenu(R.menu.font_select)
tool_bar.menu.applyTint(requireContext()) binding.toolBar.menu.applyTint(requireContext())
tool_bar.setOnMenuItemClickListener(this) binding.toolBar.setOnMenuItemClickListener(this)
adapter = FontAdapter(requireContext(), this) adapter = FontAdapter(requireContext(), this)
recycler_view.layoutManager = LinearLayoutManager(context) binding.recyclerView.layoutManager = LinearLayoutManager(context)
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
val fontPath = getPrefString(PreferKey.fontFolder) val fontPath = getPrefString(PreferKey.fontFolder)
if (fontPath.isNullOrEmpty()) { if (fontPath.isNullOrEmpty()) {

@ -6,7 +6,6 @@ import androidx.appcompat.app.AlertDialog
import io.legado.app.R import io.legado.app.R
import io.legado.app.utils.applyTint import io.legado.app.utils.applyTint
import io.legado.app.utils.hideSoftInput import io.legado.app.utils.hideSoftInput
import kotlinx.android.synthetic.main.dialog_number_picker.*
class NumberPickerDialog(context: Context) { class NumberPickerDialog(context: Context) {
@ -61,7 +60,7 @@ class NumberPickerDialog(context: Context) {
} }
builder.setNegativeButton(R.string.cancel, null) builder.setNegativeButton(R.string.cancel, null)
val dialog = builder.show().applyTint() val dialog = builder.show().applyTint()
numberPicker = dialog.number_picker numberPicker = dialog.findViewById(R.id.number_picker)
numberPicker?.let { np -> numberPicker?.let { np ->
minValue?.let { minValue?.let {
np.minValue = it np.minValue = it

@ -17,11 +17,12 @@ import io.legado.app.R
import io.legado.app.base.BaseDialogFragment import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemIconPreferenceBinding
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.utils.getCompatDrawable import io.legado.app.utils.getCompatDrawable
import io.legado.app.utils.getSize import io.legado.app.utils.getSize
import kotlinx.android.synthetic.main.dialog_recycler_view.* import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.android.synthetic.main.item_icon_preference.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
@ -117,6 +118,7 @@ class IconListPreference(context: Context, attrs: AttributeSet) : ListPreference
var dialogEntries: Array<CharSequence>? = null var dialogEntries: Array<CharSequence>? = null
var dialogEntryValues: Array<CharSequence>? = null var dialogEntryValues: Array<CharSequence>? = null
var dialogIconNames: Array<CharSequence>? = null var dialogIconNames: Array<CharSequence>? = null
private val binding by viewBinding(DialogRecyclerViewBinding::bind)
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
@ -136,11 +138,11 @@ class IconListPreference(context: Context, attrs: AttributeSet) : ListPreference
} }
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
tool_bar.setBackgroundColor(primaryColor) binding.toolBar.setBackgroundColor(primaryColor)
tool_bar.setTitle(R.string.change_icon) binding.toolBar.setTitle(R.string.change_icon)
recycler_view.layoutManager = LinearLayoutManager(requireContext()) binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
val adapter = Adapter(requireContext()) val adapter = Adapter(requireContext())
recycler_view.adapter = adapter binding.recyclerView.adapter = adapter
arguments?.let { arguments?.let {
dialogValue = it.getString("value") dialogValue = it.getString("value")
dialogEntries = it.getCharSequenceArray("entries") dialogEntries = it.getCharSequenceArray("entries")
@ -154,14 +156,15 @@ class IconListPreference(context: Context, attrs: AttributeSet) : ListPreference
inner class Adapter(context: Context) : inner class Adapter(context: Context) :
SimpleRecyclerAdapter<CharSequence>(context, R.layout.item_icon_preference) { SimpleRecyclerAdapter<CharSequence, ItemIconPreferenceBinding>(context) {
override fun convert( override fun convert(
holder: ItemViewHolder, holder: ItemViewHolder,
binding: ItemIconPreferenceBinding,
item: CharSequence, item: CharSequence,
payloads: MutableList<Any> payloads: MutableList<Any>
) { ) {
with(holder.itemView) { with(binding) {
val index = findIndexOfValue(item.toString()) val index = findIndexOfValue(item.toString())
dialogEntries?.let { dialogEntries?.let {
label.text = it[index] label.text = it[index]
@ -179,14 +182,17 @@ class IconListPreference(context: Context, attrs: AttributeSet) : ListPreference
} }
} }
label.isChecked = item.toString() == dialogValue label.isChecked = item.toString() == dialogValue
onClick { root.onClick {
onChanged?.invoke(item.toString()) onChanged?.invoke(item.toString())
this@IconDialog.dismiss() this@IconDialog.dismiss()
} }
} }
} }
override fun registerListener(holder: ItemViewHolder) { override fun registerListener(
holder: ItemViewHolder,
binding: ItemIconPreferenceBinding
) {
holder.itemView.onClick { holder.itemView.onClick {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
onChanged?.invoke(it.toString()) onChanged?.invoke(it.toString())

@ -8,12 +8,13 @@ import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.widget.AppCompatAutoCompleteTextView import androidx.appcompat.widget.AppCompatAutoCompleteTextView
import io.legado.app.R import io.legado.app.R
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.utils.gone import io.legado.app.utils.gone
import io.legado.app.utils.visible import io.legado.app.utils.visible
import kotlinx.android.synthetic.main.item_1line_text_and_del.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
@Suppress("unused") @Suppress("unused")
@ -56,9 +57,11 @@ class AutoCompleteTextView @JvmOverloads constructor(
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val view = convertView ?: LayoutInflater.from(context) val view = convertView ?: LayoutInflater.from(context)
.inflate(R.layout.item_1line_text_and_del, parent, false) .inflate(R.layout.item_1line_text_and_del, parent, false)
view.text_view.text = getItem(position) val textView = view.findViewById<TextView>(R.id.text_view)
if (delCallBack != null) view.iv_delete.visible() else view.iv_delete.gone() textView.text = getItem(position)
view.iv_delete.onClick { val ivDelete = view.findViewById<ImageView>(R.id.iv_delete)
if (delCallBack != null) ivDelete.visible() else ivDelete.gone()
ivDelete.onClick {
getItem(position)?.let { getItem(position)?.let {
remove(it) remove(it)
delCallBack?.invoke(it) delCallBack?.invoke(it)

@ -4,14 +4,14 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<ViewStub <ViewStub
android:id="@+id/errorViewStub" android:id="@+id/error_view_stub"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout="@layout/view_error" /> android:layout="@layout/view_error" />
<ViewStub <ViewStub
android:id="@+id/progressViewStub" android:id="@+id/progress_view_stub"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"

Loading…
Cancel
Save