pull/737/head
Robot 4 years ago
commit ba410116b1
  1. 1
      app/src/main/assets/updateLog.md
  2. 165
      app/src/main/java/io/legado/app/base/adapter/CommonRecyclerAdapter.kt
  3. 31
      app/src/main/java/io/legado/app/base/adapter/ItemViewDelegate.kt
  4. 258
      app/src/main/java/io/legado/app/base/adapter/SimpleRecyclerAdapter.kt
  5. 1
      app/src/main/java/io/legado/app/constant/PreferKey.kt
  6. 2
      app/src/main/java/io/legado/app/help/AppConfig.kt
  7. 1
      app/src/main/java/io/legado/app/service/help/ReadBook.kt
  8. 4
      app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt
  9. 4
      app/src/main/java/io/legado/app/ui/book/explore/ExploreShowAdapter.kt
  10. 1
      app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt
  11. 4
      app/src/main/java/io/legado/app/ui/book/read/config/BgAdapter.kt
  12. 4
      app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt
  13. 2
      app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt
  14. 2
      app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentActivity.kt
  15. 2
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  16. 2
      app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt
  17. 2
      app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt
  18. 2
      app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt
  19. 4
      app/src/main/java/io/legado/app/ui/main/rss/RssAdapter.kt
  20. 2
      app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt
  21. 4
      app/src/main/java/io/legado/app/ui/rss/article/BaseRssArticlesAdapter.kt
  22. 2
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt
  23. 2
      app/src/main/res/values-zh-rHK/strings.xml
  24. 2
      app/src/main/res/values-zh-rTW/strings.xml
  25. 2
      app/src/main/res/values-zh/strings.xml
  26. 2
      app/src/main/res/values/strings.xml
  27. 9
      app/src/main/res/xml/pref_config_backup.xml

@ -6,6 +6,7 @@
**2020/12/15**
* 修复一些引起崩溃的bug
* 修复搜书和换源可能什么分组都没有的bug
* 添加同步进度开关,默认开启
**2020/12/14**
* 修复bug

@ -4,13 +4,11 @@ import android.content.Context
import android.util.SparseArray
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import java.util.*
import kotlin.collections.ArrayList
/**
* Created by Invincible on 2017/11/24.
@ -21,27 +19,12 @@ import kotlin.collections.ArrayList
abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val context: Context) :
RecyclerView.Adapter<ItemViewHolder>() {
constructor(context: Context, vararg delegates: ItemViewDelegate<ITEM, VB>) : this(context) {
addItemViewDelegates(*delegates)
}
constructor(
context: Context,
vararg delegates: Pair<Int, ItemViewDelegate<ITEM, VB>>
) : this(context) {
addItemViewDelegates(*delegates)
}
val inflater: LayoutInflater = LayoutInflater.from(context)
private val headerItems: SparseArray<(parent: ViewGroup) -> ViewBinding> by lazy { SparseArray() }
private val footerItems: SparseArray<(parent: ViewGroup) -> ViewBinding> by lazy { SparseArray() }
private val itemDelegates: HashMap<Int, ItemViewDelegate<ITEM, VB>> = hashMapOf()
private val asyncListDiffer: AsyncListDiffer<ITEM> by lazy {
AsyncListDiffer(this, diffItemCallback)
}
private val items: MutableList<ITEM> = mutableListOf()
private val lock = Object()
@ -50,19 +33,6 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
var itemAnimation: ItemAnimation? = null
open val diffItemCallback: DiffUtil.ItemCallback<ITEM> =
object : DiffUtil.ItemCallback<ITEM>() {
override fun areItemsTheSame(oldItem: ITEM, newItem: ITEM): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: ITEM, newItem: ITEM): Boolean {
return true
}
}
fun setOnItemClickListener(listener: (holder: ItemViewHolder, item: ITEM) -> Unit) {
itemClickListener = listener
}
@ -75,28 +45,6 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
recyclerView.adapter = this
}
fun <DELEGATE : ItemViewDelegate<ITEM, VB>> addItemViewDelegate(
viewType: Int,
delegate: DELEGATE
) {
itemDelegates[viewType] = delegate
}
fun addItemViewDelegate(delegate: ItemViewDelegate<ITEM, VB>) {
itemDelegates[itemDelegates.size] = delegate
}
fun addItemViewDelegates(vararg delegates: ItemViewDelegate<ITEM, VB>) {
delegates.forEach {
addItemViewDelegate(it)
}
}
fun addItemViewDelegates(vararg delegates: Pair<Int, ItemViewDelegate<ITEM, VB>>) =
delegates.forEach {
addItemViewDelegate(it.first, it.second)
}
fun addHeaderView(header: ((parent: ViewGroup) -> ViewBinding)) {
synchronized(lock) {
val index = headerItems.size()
@ -133,65 +81,88 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
fun setItems(items: List<ITEM>?) {
synchronized(lock) {
asyncListDiffer.submitList(items)
if (this.items.isNotEmpty()) {
this.items.clear()
}
if (items != null) {
this.items.addAll(items)
}
notifyDataSetChanged()
}
}
fun setItems(items: List<ITEM>?, diffResult: DiffUtil.DiffResult) {
synchronized(lock) {
if (this.items.isNotEmpty()) {
this.items.clear()
}
if (items != null) {
this.items.addAll(items)
}
diffResult.dispatchUpdatesTo(this)
}
}
fun setItem(position: Int, item: ITEM) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
list[position] = item
asyncListDiffer.submitList(list)
val oldSize = getActualItemCount()
if (position in 0 until oldSize) {
this.items[position] = item
notifyItemChanged(position + getHeaderCount())
}
}
}
fun addItem(item: ITEM) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
list.add(item)
asyncListDiffer.submitList(list)
val oldSize = getActualItemCount()
if (this.items.add(item)) {
notifyItemInserted(oldSize + getHeaderCount())
}
}
}
fun addItems(position: Int, newItems: List<ITEM>) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
list.addAll(position, newItems)
asyncListDiffer.submitList(list)
if (this.items.addAll(position, newItems)) {
notifyItemRangeInserted(position + getHeaderCount(), newItems.size)
}
}
}
fun addItems(newItems: List<ITEM>) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
list.addAll(newItems)
asyncListDiffer.submitList(list)
val oldSize = getActualItemCount()
if (this.items.addAll(newItems)) {
if (oldSize == 0 && getHeaderCount() == 0) {
notifyDataSetChanged()
} else {
notifyItemRangeInserted(oldSize + getHeaderCount(), newItems.size)
}
}
}
}
fun removeItem(position: Int) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
if (list.removeAt(position) != null) {
asyncListDiffer.submitList(list)
if (this.items.removeAt(position) != null) {
notifyItemRemoved(position + getHeaderCount())
}
}
}
fun removeItem(item: ITEM) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
if (list.remove(item)) {
asyncListDiffer.submitList(list)
if (this.items.remove(item)) {
notifyItemRemoved(this.items.indexOf(item) + getHeaderCount())
}
}
}
fun removeItems(items: List<ITEM>) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
if (list.removeAll(items)) {
asyncListDiffer.submitList(list)
if (this.items.removeAll(items)) {
notifyDataSetChanged()
}
}
}
@ -202,7 +173,7 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
if (oldPosition in 0 until size && newPosition in 0 until size) {
val srcPosition = oldPosition + getHeaderCount()
val targetPosition = newPosition + getHeaderCount()
Collections.swap(asyncListDiffer.currentList, srcPosition, targetPosition)
Collections.swap(this.items, srcPosition, targetPosition)
notifyItemChanged(srcPosition)
notifyItemChanged(targetPosition)
}
@ -211,9 +182,9 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
fun updateItem(item: ITEM) =
synchronized(lock) {
val index = asyncListDiffer.currentList.indexOf(item)
val index = this.items.indexOf(item)
if (index >= 0) {
asyncListDiffer.currentList[index] = item
this.items[index] = item
notifyItemChanged(index)
}
}
@ -240,17 +211,18 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
fun clearItems() =
synchronized(lock) {
asyncListDiffer.submitList(arrayListOf())
this.items.clear()
notifyDataSetChanged()
}
fun isEmpty() = asyncListDiffer.currentList.isEmpty()
fun isEmpty() = items.isEmpty()
fun isNotEmpty() = asyncListDiffer.currentList.isNotEmpty()
fun isNotEmpty() = items.isNotEmpty()
/**
* 除去header和footer
*/
fun getActualItemCount() = asyncListDiffer.currentList.size
fun getActualItemCount() = items.size
fun getHeaderCount() = headerItems.size()
@ -258,12 +230,11 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
fun getFooterCount() = footerItems.size()
fun getItem(position: Int): ITEM? = asyncListDiffer.currentList.getOrNull(position)
fun getItem(position: Int): ITEM? = items.getOrNull(position)
fun getItemByLayoutPosition(position: Int) =
asyncListDiffer.currentList.getOrNull(position - getHeaderCount())
fun getItemByLayoutPosition(position: Int) = items.getOrNull(position - getHeaderCount())
fun getItems(): List<ITEM> = asyncListDiffer.currentList
fun getItems(): List<ITEM> = items
protected open fun getItemViewType(item: ITEM, position: Int) = 0
@ -295,8 +266,7 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
val holder = ItemViewHolder(getViewBinding(parent))
@Suppress("UNCHECKED_CAST")
itemDelegates.getValue(viewType)
.registerListener(holder, (holder.binding as VB))
registerListener(holder, (holder.binding as VB))
if (itemClickListener != null) {
holder.itemView.setOnClickListener {
@ -330,8 +300,7 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
) {
if (!isHeader(holder.layoutPosition) && !isFooter(holder.layoutPosition)) {
getItem(holder.layoutPosition - getHeaderCount())?.let {
itemDelegates.getValue(getItemViewType(holder.layoutPosition))
.convert(holder, (holder.binding as VB), it, payloads)
convert(holder, (holder.binding as VB), it, payloads)
}
}
}
@ -381,6 +350,22 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
}
}
/**
* 如果使用了事件回调,回调里不要直接使用item,会出现不更新的问题,
* 使用getItem(holder.layoutPosition)来获取item
*/
abstract fun convert(
holder: ItemViewHolder,
binding: VB,
item: ITEM,
payloads: MutableList<Any>
)
/**
* 注册事件
*/
abstract fun registerListener(holder: ItemViewHolder, binding: VB)
companion object {
private const val TYPE_HEADER_VIEW = Int.MIN_VALUE
private const val TYPE_FOOTER_VIEW = Int.MAX_VALUE - 999

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

@ -1,30 +1,265 @@
package io.legado.app.base.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import java.util.*
import kotlin.collections.ArrayList
/**
* Created by Invincible on 2017/12/15.
*/
abstract class SimpleRecyclerAdapter<ITEM, VB : ViewBinding>(context: Context) :
CommonRecyclerAdapter<ITEM, VB>(context) {
@Suppress("unused")
abstract class SimpleRecyclerAdapter<ITEM, VB : ViewBinding>(protected val context: Context) :
RecyclerView.Adapter<ItemViewHolder>() {
init {
addItemViewDelegate(object : ItemViewDelegate<ITEM, VB>(context) {
val inflater: LayoutInflater = LayoutInflater.from(context)
override fun convert(
private val asyncListDiffer: AsyncListDiffer<ITEM> by lazy {
AsyncListDiffer(this, diffItemCallback)
}
private val lock = Object()
private var itemClickListener: ((holder: ItemViewHolder, item: ITEM) -> Unit)? = null
private var itemLongClickListener: ((holder: ItemViewHolder, item: ITEM) -> Boolean)? = null
var itemAnimation: ItemAnimation? = null
open val diffItemCallback: DiffUtil.ItemCallback<ITEM> =
object : DiffUtil.ItemCallback<ITEM>() {
override fun areItemsTheSame(oldItem: ITEM, newItem: ITEM): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: ITEM, newItem: ITEM): Boolean {
return true
}
}
fun setOnItemClickListener(listener: (holder: ItemViewHolder, item: ITEM) -> Unit) {
itemClickListener = listener
}
fun setOnItemLongClickListener(listener: (holder: ItemViewHolder, item: ITEM) -> Boolean) {
itemLongClickListener = listener
}
fun bindToRecyclerView(recyclerView: RecyclerView) {
recyclerView.adapter = this
}
fun setItems(items: List<ITEM>?) {
synchronized(lock) {
asyncListDiffer.submitList(items)
}
}
fun setItem(position: Int, item: ITEM) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
list[position] = item
asyncListDiffer.submitList(list)
}
}
fun addItem(item: ITEM) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
list.add(item)
asyncListDiffer.submitList(list)
}
}
fun addItems(position: Int, newItems: List<ITEM>) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
list.addAll(position, newItems)
asyncListDiffer.submitList(list)
}
}
fun addItems(newItems: List<ITEM>) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
list.addAll(newItems)
asyncListDiffer.submitList(list)
}
}
fun removeItem(position: Int) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
if (list.removeAt(position) != null) {
asyncListDiffer.submitList(list)
}
}
}
fun removeItem(item: ITEM) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
if (list.remove(item)) {
asyncListDiffer.submitList(list)
}
}
}
fun removeItems(items: List<ITEM>) {
synchronized(lock) {
val list = ArrayList(asyncListDiffer.currentList)
if (list.removeAll(items)) {
asyncListDiffer.submitList(list)
}
}
}
fun swapItem(oldPosition: Int, newPosition: Int) {
synchronized(lock) {
val size = itemCount
if (oldPosition in 0 until size && newPosition in 0 until size) {
Collections.swap(asyncListDiffer.currentList, oldPosition, newPosition)
notifyItemChanged(oldPosition)
notifyItemChanged(newPosition)
}
}
}
fun updateItem(item: ITEM) =
synchronized(lock) {
val index = asyncListDiffer.currentList.indexOf(item)
if (index >= 0) {
asyncListDiffer.currentList[index] = item
notifyItemChanged(index)
}
}
fun updateItem(position: Int, payload: Any) =
synchronized(lock) {
val size = itemCount
if (position in 0 until size) {
notifyItemChanged(position, payload)
}
}
fun updateItems(fromPosition: Int, toPosition: Int, payloads: Any) =
synchronized(lock) {
val size = itemCount
if (fromPosition in 0 until size && toPosition in 0 until size) {
notifyItemRangeChanged(
fromPosition,
toPosition - fromPosition + 1,
payloads
)
}
}
fun clearItems() =
synchronized(lock) {
asyncListDiffer.submitList(arrayListOf())
}
fun isEmpty() = asyncListDiffer.currentList.isEmpty()
fun isNotEmpty() = asyncListDiffer.currentList.isNotEmpty()
fun getItem(position: Int): ITEM? = asyncListDiffer.currentList.getOrNull(position)
fun getItems(): List<ITEM> = asyncListDiffer.currentList
/**
* grid 模式下使用
*/
protected open fun getSpanSize(viewType: Int, position: Int) = 1
final override fun getItemCount() = getItems().size
final override fun getItemViewType(position: Int): Int {
return 0
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
val holder = ItemViewHolder(getViewBinding(parent))
@Suppress("UNCHECKED_CAST")
registerListener(holder, (holder.binding as VB))
if (itemClickListener != null) {
holder.itemView.setOnClickListener {
getItem(holder.layoutPosition)?.let {
itemClickListener?.invoke(holder, it)
}
}
}
if (itemLongClickListener != null) {
holder.itemView.setOnLongClickListener {
getItem(holder.layoutPosition)?.let {
itemLongClickListener?.invoke(holder, it) ?: true
} ?: true
}
}
return holder
}
protected abstract fun getViewBinding(parent: ViewGroup): VB
final override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {}
@Suppress("UNCHECKED_CAST")
final override fun onBindViewHolder(
holder: ItemViewHolder,
binding: VB,
item: ITEM,
position: Int,
payloads: MutableList<Any>
) {
this@SimpleRecyclerAdapter.convert(holder, binding, item, payloads)
getItem(holder.layoutPosition)?.let {
convert(holder, (holder.binding as VB), it, payloads)
}
}
override fun onViewAttachedToWindow(holder: ItemViewHolder) {
super.onViewAttachedToWindow(holder)
addAnimation(holder)
}
override fun registerListener(holder: ItemViewHolder, binding: VB) {
this@SimpleRecyclerAdapter.registerListener(holder, binding)
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
val manager = recyclerView.layoutManager
if (manager is GridLayoutManager) {
manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return getSpanSize(getItemViewType(position), position)
}
}
}
}
private fun addAnimation(holder: ItemViewHolder) {
itemAnimation?.let {
if (it.itemAnimEnabled) {
if (!it.itemAnimFirstOnly || holder.layoutPosition > it.itemAnimStartPosition) {
startAnimation(holder, it)
it.itemAnimStartPosition = holder.layoutPosition
}
}
}
}
protected open fun startAnimation(holder: ItemViewHolder, item: ItemAnimation) {
item.itemAnimation?.let {
for (anim in it.getAnimators(holder.itemView)) {
anim.setDuration(item.itemAnimDuration).start()
anim.interpolator = item.itemAnimInterpolator
}
}
})
}
/**
@ -42,4 +277,5 @@ abstract class SimpleRecyclerAdapter<ITEM, VB : ViewBinding>(context: Context) :
* 注册事件
*/
abstract fun registerListener(holder: ItemViewHolder, binding: VB)
}

@ -63,6 +63,7 @@ object PreferKey {
const val autoChangeSource = "autoChangeSource"
const val importKeepName = "importKeepName"
const val screenDirection = "screenDirection"
const val syncBookProgress = "syncBookProgress"
const val cPrimary = "colorPrimary"
const val cAccent = "colorAccent"

@ -147,6 +147,8 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
val importKeepName get() = context.getPrefBoolean(PreferKey.importKeepName)
val syncBookProgress get() = context.getPrefBoolean(PreferKey.syncBookProgress, true)
private fun getPrefUserAgent(): String {
val ua = context.getPrefString(PreferKey.userAgent)
if (ua.isNullOrBlank()) {

@ -91,6 +91,7 @@ object ReadBook {
}
fun uploadProgress() {
if (!AppConfig.syncBookProgress) return
book?.let {
BookWebDav.uploadBookProgress(it)
}

@ -163,7 +163,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
}
adapter.cacheChapters[book.bookUrl] = chapterCaches
withContext(Dispatchers.Main) {
adapter.notifyItemRangeChanged(0, adapter.getActualItemCount(), true)
adapter.notifyItemRangeChanged(0, adapter.itemCount, true)
}
}
}
@ -179,7 +179,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
menu?.applyTint(this)
}
adapter.downloadMap = it
adapter.notifyItemRangeChanged(0, adapter.getActualItemCount(), true)
adapter.notifyItemRangeChanged(0, adapter.itemCount, true)
}
observeEvent<BookChapter>(EventBus.SAVE_CONTENT) {
adapter.cacheChapters[it.bookUrl]?.add(it.url)

@ -3,8 +3,8 @@ package io.legado.app.ui.book.explore
import android.content.Context
import android.view.ViewGroup
import io.legado.app.R
import io.legado.app.base.adapter.CommonRecyclerAdapter
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.SearchBook
import io.legado.app.databinding.ItemSearchBinding
@ -13,7 +13,7 @@ import io.legado.app.utils.visible
import org.jetbrains.anko.sdk27.listeners.onClick
class ExploreShowAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<SearchBook, ItemSearchBinding>(context) {
CommonRecyclerAdapter<SearchBook, ItemSearchBinding>(context) {
override fun getViewBinding(parent: ViewGroup): ItemSearchBinding {
return ItemSearchBinding.inflate(inflater, parent, false)

@ -163,6 +163,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
}
fun syncBookProgress(book: Book) {
if (!AppConfig.syncBookProgress)
execute {
BookWebDav.getBookProgress(book)?.let { progress ->
if (progress.durChapterIndex < book.durChapterIndex ||

@ -2,8 +2,8 @@ package io.legado.app.ui.book.read.config
import android.content.Context
import android.view.ViewGroup
import io.legado.app.base.adapter.CommonRecyclerAdapter
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.EventBus
import io.legado.app.databinding.ItemBgImageBinding
import io.legado.app.help.ImageLoader
@ -13,7 +13,7 @@ import org.jetbrains.anko.sdk27.listeners.onClick
import java.io.File
class BgAdapter(context: Context, val textColor: Int) :
SimpleRecyclerAdapter<String, ItemBgImageBinding>(context) {
CommonRecyclerAdapter<String, ItemBgImageBinding>(context) {
override fun getViewBinding(parent: ViewGroup): ItemBgImageBinding {
return ItemBgImageBinding.inflate(inflater, parent, false)

@ -6,8 +6,8 @@ import android.view.*
import androidx.core.view.get
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
import io.legado.app.base.adapter.CommonRecyclerAdapter
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.constant.EventBus
import io.legado.app.databinding.DialogReadBookStyleBinding
import io.legado.app.databinding.ItemReadStyleBinding
@ -207,7 +207,7 @@ class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack {
}
inner class StyleAdapter :
SimpleRecyclerAdapter<ReadBookConfig.Config, ItemReadStyleBinding>(requireContext()) {
CommonRecyclerAdapter<ReadBookConfig.Config, ItemReadStyleBinding>(requireContext()) {
override fun getViewBinding(parent: ViewGroup): ItemReadStyleBinding {
return ItemReadStyleBinding.inflate(inflater, parent, false)

@ -151,7 +151,7 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
cbName.onClick {
getItem(holder.layoutPosition)?.let { httpTTS ->
engineId = httpTTS.id
notifyItemRangeChanged(0, getActualItemCount())
notifyItemRangeChanged(0, itemCount)
}
}
ivEdit.onClick {

@ -117,7 +117,7 @@ class SearchContentActivity :
launch(Dispatchers.IO) {
adapter.cacheFileNames.addAll(BookHelp.getChapterFiles(book))
withContext(Dispatchers.Main) {
adapter.notifyItemRangeChanged(0, adapter.getActualItemCount(), true)
adapter.notifyItemRangeChanged(0, adapter.itemCount, true)
}
}
}

@ -399,7 +399,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
override fun upCountView() {
binding.selectActionBar
.upCountView(adapter.getSelection().size, adapter.getActualItemCount())
.upCountView(adapter.getSelection().size, adapter.itemCount)
}
override fun onQueryTextChange(newText: String?): Boolean {

@ -102,7 +102,7 @@ class ChapterListFragment : VMBaseFragment<ChapterListViewModel>(R.layout.fragme
launch(IO) {
adapter.cacheFileNames.addAll(BookHelp.getChapterFiles(book))
withContext(Main) {
adapter.notifyItemRangeChanged(0, adapter.getActualItemCount(), true)
adapter.notifyItemRangeChanged(0, adapter.itemCount, true)
}
}
}

@ -134,7 +134,7 @@ class BooksFragment : BaseFragment(R.layout.fragment_books),
}
fun getBooksCount(): Int {
return booksAdapter.getActualItemCount()
return booksAdapter.itemCount
}
override fun open(book: Book) {

@ -39,7 +39,7 @@ class ExploreAdapter(context: Context, private val scope: CoroutineScope, val ca
payloads: MutableList<Any>
) {
with(binding) {
if (holder.layoutPosition == getActualItemCount() - 1) {
if (holder.layoutPosition == itemCount - 1) {
root.setPadding(16.dp, 12.dp, 16.dp, 12.dp)
} else {
root.setPadding(16.dp, 12.dp, 16.dp, 0)

@ -5,8 +5,8 @@ import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.PopupMenu
import io.legado.app.R
import io.legado.app.base.adapter.CommonRecyclerAdapter
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.RssSource
import io.legado.app.databinding.ItemRssBinding
import io.legado.app.help.ImageLoader
@ -14,7 +14,7 @@ import org.jetbrains.anko.sdk27.listeners.onClick
import org.jetbrains.anko.sdk27.listeners.onLongClick
class RssAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<RssSource, ItemRssBinding>(context) {
CommonRecyclerAdapter<RssSource, ItemRssBinding>(context) {
override fun getViewBinding(parent: ViewGroup): ItemRssBinding {
return ItemRssBinding.inflate(inflater, parent, false)

@ -281,7 +281,7 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
override fun upCountView() {
binding.selectActionBar.upCountView(
adapter.getSelection().size,
adapter.getActualItemCount()
adapter.itemCount
)
}

@ -2,12 +2,12 @@ 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.base.adapter.CommonRecyclerAdapter
import io.legado.app.data.entities.RssArticle
abstract class BaseRssArticlesAdapter<VB : ViewBinding>(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<RssArticle, VB>(context) {
CommonRecyclerAdapter<RssArticle, VB>(context) {
interface CallBack {
val isGridLayout: Boolean

@ -221,7 +221,7 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
override fun upCountView() {
binding.selectActionBar.upCountView(
adapter.getSelection().size,
adapter.getActualItemCount()
adapter.itemCount
)
}

@ -790,5 +790,7 @@
<string name="rule_sub_empty_msg">添加大佬们提供的规则导入地址\n添加后点击可导入规则</string>
<string name="get_book_progress">拉取云端进度</string>
<string name="current_progress_exceeds_cloud">当前进度超过云端进度,是否同步?</string>
<string name="sync_book_progress_t">同步阅读进度</string>
<string name="sync_book_progress_s">进入退出阅读界面时同步阅读进度</string>
</resources>

@ -791,5 +791,7 @@
<string name="rule_sub_empty_msg">添加大佬们提供的规则导入地址\n添加后点击可导入规则</string>
<string name="get_book_progress">拉取云端进度</string>
<string name="current_progress_exceeds_cloud">当前进度超过云端进度,是否同步?</string>
<string name="sync_book_progress_t">同步阅读进度</string>
<string name="sync_book_progress_s">进入退出阅读界面时同步阅读进度</string>
</resources>

@ -794,5 +794,7 @@
<string name="rule_sub_empty_msg">添加大佬们提供的规则导入地址\n添加后点击可导入规则</string>
<string name="get_book_progress">拉取云端进度</string>
<string name="current_progress_exceeds_cloud">当前进度超过云端进度,是否同步?</string>
<string name="sync_book_progress_t">同步阅读进度</string>
<string name="sync_book_progress_s">进入退出阅读界面时同步阅读进度</string>
</resources>

@ -797,5 +797,7 @@
<string name="rule_sub_empty_msg">添加大佬们提供的规则导入地址\n添加后点击可导入规则</string>
<string name="get_book_progress">拉取云端进度</string>
<string name="current_progress_exceeds_cloud">当前进度超过云端进度,是否同步?</string>
<string name="sync_book_progress_t">同步阅读进度</string>
<string name="sync_book_progress_s">进入退出阅读界面时同步阅读进度</string>
</resources>

@ -36,6 +36,15 @@
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.SwitchPreference
android:key="syncBookProgress"
android:defaultValue="true"
android:title="@string/sync_book_progress_t"
android:summary="@string/sync_book_progress_s"
app:allowDividerAbove="false"
app:allowDividerBelow="false"
app:iconSpaceReserved="false" />
<io.legado.app.ui.widget.prefs.SwitchPreference
android:key="webDavCacheBackup"
android:defaultValue="false"

Loading…
Cancel
Save