pull/737/head
Robot 4 years ago
commit a1af4ca986
  1. 4
      app/build.gradle
  2. 4
      app/src/main/assets/updateLog.md
  3. 109
      app/src/main/java/io/legado/app/base/adapter/CommonRecyclerAdapter.kt
  4. 50
      app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt
  5. 2
      app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt
  6. 23
      app/src/main/java/io/legado/app/ui/book/search/DiffCallBack.kt
  7. 4
      app/src/main/java/io/legado/app/ui/book/search/SearchAdapter.kt
  8. 5
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  9. 4
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt
  10. 25
      app/src/main/java/io/legado/app/ui/book/source/manage/DiffCallBack.kt
  11. 4
      app/src/main/java/io/legado/app/ui/main/bookshelf/books/BaseBooksAdapter.kt
  12. 23
      app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksDiffCallBack.kt
  13. 5
      app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt
  14. 26
      app/src/main/java/io/legado/app/ui/replace/DiffCallBack.kt
  15. 5
      app/src/main/java/io/legado/app/ui/replace/ReplaceRuleActivity.kt
  16. 25
      app/src/main/java/io/legado/app/ui/rss/source/manage/DiffCallBack.kt
  17. 5
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt
  18. 4
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceAdapter.kt

@ -173,8 +173,8 @@ dependencies {
// //
implementation 'com.squareup.okhttp3:okhttp:4.9.0' implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'com.ljx.rxhttp:rxhttp:2.4.4-beta4' implementation 'com.ljx.rxhttp:rxhttp:2.5.1'
kapt 'com.ljx.rxhttp:rxhttp-compiler:2.4.4-beta4' kapt 'com.ljx.rxhttp:rxhttp-compiler:2.5.1'
//Glide //Glide
implementation 'com.github.bumptech.glide:glide:4.11.0' implementation 'com.github.bumptech.glide:glide:4.11.0'

@ -3,6 +3,10 @@
* 关注合作公众号 **[小说拾遗]** 获取好看的小说。 * 关注合作公众号 **[小说拾遗]** 获取好看的小说。
* 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。
**2020/12/15**
* 修复一些引起崩溃的bug
* 修复搜书和换源可能什么分组都没有的bug
**2020/12/14** **2020/12/14**
* 修复bug * 修复bug
* 电池图标不允许改字体 * 电池图标不允许改字体

@ -4,11 +4,13 @@ import android.content.Context
import android.util.SparseArray import android.util.SparseArray
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import java.util.* import java.util.*
import kotlin.collections.ArrayList
/** /**
* Created by Invincible on 2017/11/24. * Created by Invincible on 2017/11/24.
@ -36,7 +38,10 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
private val footerItems: 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 itemDelegates: HashMap<Int, ItemViewDelegate<ITEM, VB>> = hashMapOf()
private val items: MutableList<ITEM> = mutableListOf()
private val asyncListDiffer: AsyncListDiffer<ITEM> by lazy {
AsyncListDiffer(this, diffItemCallback)
}
private val lock = Object() private val lock = Object()
@ -45,6 +50,19 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
var itemAnimation: ItemAnimation? = 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) { fun setOnItemClickListener(listener: (holder: ItemViewHolder, item: ITEM) -> Unit) {
itemClickListener = listener itemClickListener = listener
} }
@ -115,88 +133,65 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
fun setItems(items: List<ITEM>?) { fun setItems(items: List<ITEM>?) {
synchronized(lock) { synchronized(lock) {
if (this.items.isNotEmpty()) { asyncListDiffer.submitList(items)
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) { fun setItem(position: Int, item: ITEM) {
synchronized(lock) { synchronized(lock) {
val oldSize = getActualItemCount() val list = ArrayList(asyncListDiffer.currentList)
if (position in 0 until oldSize) { list[position] = item
this.items[position] = item asyncListDiffer.submitList(list)
notifyItemChanged(position + getHeaderCount())
}
} }
} }
fun addItem(item: ITEM) { fun addItem(item: ITEM) {
synchronized(lock) { synchronized(lock) {
val oldSize = getActualItemCount() val list = ArrayList(asyncListDiffer.currentList)
if (this.items.add(item)) { list.add(item)
notifyItemInserted(oldSize + getHeaderCount()) asyncListDiffer.submitList(list)
}
} }
} }
fun addItems(position: Int, newItems: List<ITEM>) { fun addItems(position: Int, newItems: List<ITEM>) {
synchronized(lock) { synchronized(lock) {
if (this.items.addAll(position, newItems)) { val list = ArrayList(asyncListDiffer.currentList)
notifyItemRangeInserted(position + getHeaderCount(), newItems.size) list.addAll(position, newItems)
} asyncListDiffer.submitList(list)
} }
} }
fun addItems(newItems: List<ITEM>) { fun addItems(newItems: List<ITEM>) {
synchronized(lock) { synchronized(lock) {
val oldSize = getActualItemCount() val list = ArrayList(asyncListDiffer.currentList)
if (this.items.addAll(newItems)) { list.addAll(newItems)
if (oldSize == 0 && getHeaderCount() == 0) { asyncListDiffer.submitList(list)
notifyDataSetChanged()
} else {
notifyItemRangeInserted(oldSize + getHeaderCount(), newItems.size)
}
}
} }
} }
fun removeItem(position: Int) { fun removeItem(position: Int) {
synchronized(lock) { synchronized(lock) {
if (this.items.removeAt(position) != null) { val list = ArrayList(asyncListDiffer.currentList)
notifyItemRemoved(position + getHeaderCount()) if (list.removeAt(position) != null) {
asyncListDiffer.submitList(list)
} }
} }
} }
fun removeItem(item: ITEM) { fun removeItem(item: ITEM) {
synchronized(lock) { synchronized(lock) {
if (this.items.remove(item)) { val list = ArrayList(asyncListDiffer.currentList)
notifyItemRemoved(this.items.indexOf(item) + getHeaderCount()) if (list.remove(item)) {
asyncListDiffer.submitList(list)
} }
} }
} }
fun removeItems(items: List<ITEM>) { fun removeItems(items: List<ITEM>) {
synchronized(lock) { synchronized(lock) {
if (this.items.removeAll(items)) { val list = ArrayList(asyncListDiffer.currentList)
notifyDataSetChanged() if (list.removeAll(items)) {
asyncListDiffer.submitList(list)
} }
} }
} }
@ -207,7 +202,7 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
if (oldPosition in 0 until size && newPosition in 0 until size) { if (oldPosition in 0 until size && newPosition in 0 until size) {
val srcPosition = oldPosition + getHeaderCount() val srcPosition = oldPosition + getHeaderCount()
val targetPosition = newPosition + getHeaderCount() val targetPosition = newPosition + getHeaderCount()
Collections.swap(this.items, srcPosition, targetPosition) Collections.swap(asyncListDiffer.currentList, srcPosition, targetPosition)
notifyItemChanged(srcPosition) notifyItemChanged(srcPosition)
notifyItemChanged(targetPosition) notifyItemChanged(targetPosition)
} }
@ -216,9 +211,9 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
fun updateItem(item: ITEM) = fun updateItem(item: ITEM) =
synchronized(lock) { synchronized(lock) {
val index = this.items.indexOf(item) val index = asyncListDiffer.currentList.indexOf(item)
if (index >= 0) { if (index >= 0) {
this.items[index] = item asyncListDiffer.currentList[index] = item
notifyItemChanged(index) notifyItemChanged(index)
} }
} }
@ -245,18 +240,17 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
fun clearItems() = fun clearItems() =
synchronized(lock) { synchronized(lock) {
this.items.clear() asyncListDiffer.submitList(arrayListOf())
notifyDataSetChanged()
} }
fun isEmpty() = items.isEmpty() fun isEmpty() = asyncListDiffer.currentList.isEmpty()
fun isNotEmpty() = items.isNotEmpty() fun isNotEmpty() = asyncListDiffer.currentList.isNotEmpty()
/** /**
* 除去header和footer * 除去header和footer
*/ */
fun getActualItemCount() = items.size fun getActualItemCount() = asyncListDiffer.currentList.size
fun getHeaderCount() = headerItems.size() fun getHeaderCount() = headerItems.size()
@ -264,11 +258,12 @@ abstract class CommonRecyclerAdapter<ITEM, VB : ViewBinding>(protected val conte
fun getFooterCount() = footerItems.size() fun getFooterCount() = footerItems.size()
fun getItem(position: Int): ITEM? = items.getOrNull(position) fun getItem(position: Int): ITEM? = asyncListDiffer.currentList.getOrNull(position)
fun getItemByLayoutPosition(position: Int) = items.getOrNull(position - getHeaderCount()) fun getItemByLayoutPosition(position: Int) =
asyncListDiffer.currentList.getOrNull(position - getHeaderCount())
fun getItems(): List<ITEM> = items fun getItems(): List<ITEM> = asyncListDiffer.currentList
protected open fun getItemViewType(item: ITEM, position: Int) = 0 protected open fun getItemViewType(item: ITEM, position: Int) = 0

@ -32,7 +32,6 @@ import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.util.* import java.util.*
import kotlin.collections.ArrayList
class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener { class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
private lateinit var viewModel: GroupViewModel private lateinit var viewModel: GroupViewModel
@ -77,9 +76,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
private fun initData() { private fun initData() {
App.db.bookGroupDao.liveDataAll().observe(viewLifecycleOwner, { App.db.bookGroupDao.liveDataAll().observe(viewLifecycleOwner, {
val diffResult = adapter.setItems(it)
DiffUtil.calculateDiff(GroupDiffCallBack(ArrayList(adapter.getItems()), it))
adapter.setItems(it, diffResult)
}) })
} }
@ -140,40 +137,29 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
}.show() }.show()
} }
private class GroupDiffCallBack(
private val oldItems: List<BookGroup>,
private val newItems: List<BookGroup>
) : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return oldItems.size
}
override fun getNewListSize(): Int {
return newItems.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
return oldItem.groupId == newItem.groupId
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
return oldItem.groupName == newItem.groupName
&& oldItem.show == newItem.show
}
}
private inner class GroupAdapter(context: Context) : private inner class GroupAdapter(context: Context) :
SimpleRecyclerAdapter<BookGroup, ItemGroupManageBinding>(context), SimpleRecyclerAdapter<BookGroup, ItemGroupManageBinding>(context),
ItemTouchCallback.Callback { ItemTouchCallback.Callback {
private var isMoved = false private var isMoved = false
override val diffItemCallback: DiffUtil.ItemCallback<BookGroup>
get() = object : DiffUtil.ItemCallback<BookGroup>() {
override fun areItemsTheSame(oldItem: BookGroup, newItem: BookGroup): Boolean {
return oldItem.groupId == newItem.groupId
}
override fun areContentsTheSame(
oldItem: BookGroup,
newItem: BookGroup
): Boolean {
return oldItem.groupName == newItem.groupName
&& oldItem.show == newItem.show
}
}
override fun getViewBinding(parent: ViewGroup): ItemGroupManageBinding { override fun getViewBinding(parent: ViewGroup): ItemGroupManageBinding {
return ItemGroupManageBinding.inflate(inflater, parent, false) return ItemGroupManageBinding.inflate(inflater, parent, false)
} }

@ -287,7 +287,7 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
private fun importNetConfig(url: String) { private fun importNetConfig(url: String) {
execute { execute {
RxHttp.get(url).toByteArray().await()?.let { RxHttp.get(url).toByteArray().await().let {
importConfig(it) importConfig(it)
} }
}.onError { }.onError {

@ -4,20 +4,9 @@ import android.os.Bundle
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.SearchBook
class DiffCallBack(private val oldItems: List<SearchBook>, private val newItems: List<SearchBook>) : class DiffCallBack : DiffUtil.ItemCallback<SearchBook>() {
DiffUtil.Callback() {
override fun getNewListSize(): Int { override fun areItemsTheSame(oldItem: SearchBook, newItem: SearchBook): Boolean {
return newItems.size
}
override fun getOldListSize(): Int {
return oldItems.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
return when { return when {
oldItem.name != newItem.name -> false oldItem.name != newItem.name -> false
oldItem.author != newItem.author -> false oldItem.author != newItem.author -> false
@ -25,9 +14,7 @@ class DiffCallBack(private val oldItems: List<SearchBook>, private val newItems:
} }
} }
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { override fun areContentsTheSame(oldItem: SearchBook, newItem: SearchBook): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
return when { return when {
oldItem.origins.size != newItem.origins.size -> false oldItem.origins.size != newItem.origins.size -> false
oldItem.coverUrl != newItem.coverUrl -> false oldItem.coverUrl != newItem.coverUrl -> false
@ -38,10 +25,8 @@ class DiffCallBack(private val oldItems: List<SearchBook>, private val newItems:
} }
} }
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? { override fun getChangePayload(oldItem: SearchBook, newItem: SearchBook): Any? {
val payload = Bundle() val payload = Bundle()
val newItem = newItems[newItemPosition]
val oldItem = oldItems[oldItemPosition]
if (oldItem.name != newItem.name) payload.putString("name", newItem.name) if (oldItem.name != newItem.name) payload.putString("name", newItem.name)
if (oldItem.author != newItem.author) payload.putString("author", newItem.author) if (oldItem.author != newItem.author) payload.putString("author", newItem.author)
if (oldItem.origins.size != newItem.origins.size) if (oldItem.origins.size != newItem.origins.size)

@ -3,6 +3,7 @@ package io.legado.app.ui.book.search
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
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
@ -15,6 +16,9 @@ import org.jetbrains.anko.sdk27.listeners.onClick
class SearchAdapter(context: Context, val callBack: CallBack) : class SearchAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<SearchBook, ItemSearchBinding>(context) { SimpleRecyclerAdapter<SearchBook, ItemSearchBinding>(context) {
override val diffItemCallback: DiffUtil.ItemCallback<SearchBook>
get() = DiffCallBack()
override fun getViewBinding(parent: ViewGroup): ItemSearchBinding { override fun getViewBinding(parent: ViewGroup): ItemSearchBinding {
return ItemSearchBinding.inflate(inflater, parent, false) return ItemSearchBinding.inflate(inflater, parent, false)
} }

@ -11,7 +11,6 @@ import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
@ -207,9 +206,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
Sort.Update -> data.sortedBy { it.lastUpdateTime } Sort.Update -> data.sortedBy { it.lastUpdateTime }
else -> data.reversed() else -> data.reversed()
} }
val diffResult = DiffUtil adapter.setItems(sourceList)
.calculateDiff(DiffCallBack(ArrayList(adapter.getItems()), sourceList))
adapter.setItems(sourceList, diffResult)
upCountView() upCountView()
}) })
} }

@ -8,6 +8,7 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.PopupMenu import android.widget.PopupMenu
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
@ -26,6 +27,9 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<BookSource, ItemBookSourceBinding>(context), SimpleRecyclerAdapter<BookSource, ItemBookSourceBinding>(context),
Callback { Callback {
override val diffItemCallback: DiffUtil.ItemCallback<BookSource>
get() = DiffCallBack()
private val selected = linkedSetOf<BookSource>() private val selected = linkedSetOf<BookSource>()
override fun getViewBinding(parent: ViewGroup): ItemBookSourceBinding { override fun getViewBinding(parent: ViewGroup): ItemBookSourceBinding {

@ -4,28 +4,13 @@ import android.os.Bundle
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
class DiffCallBack( class DiffCallBack : DiffUtil.ItemCallback<BookSource>() {
private val oldItems: List<BookSource>,
private val newItems: List<BookSource>
) : DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { override fun areItemsTheSame(oldItem: BookSource, newItem: BookSource): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
return oldItem.bookSourceUrl == newItem.bookSourceUrl return oldItem.bookSourceUrl == newItem.bookSourceUrl
} }
override fun getOldListSize(): Int { override fun areContentsTheSame(oldItem: BookSource, newItem: BookSource): Boolean {
return oldItems.size
}
override fun getNewListSize(): Int {
return newItems.size
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
if (oldItem.bookSourceName != newItem.bookSourceName) if (oldItem.bookSourceName != newItem.bookSourceName)
return false return false
if (oldItem.bookSourceGroup != newItem.bookSourceGroup) if (oldItem.bookSourceGroup != newItem.bookSourceGroup)
@ -40,9 +25,7 @@ class DiffCallBack(
return true return true
} }
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? { override fun getChangePayload(oldItem: BookSource, newItem: BookSource): Any? {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
val payload = Bundle() val payload = Bundle()
if (oldItem.bookSourceName != newItem.bookSourceName) { if (oldItem.bookSourceName != newItem.bookSourceName) {
payload.putString("name", newItem.bookSourceName) payload.putString("name", newItem.bookSourceName)

@ -2,6 +2,7 @@ package io.legado.app.ui.main.bookshelf.books
import android.content.Context import android.content.Context
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.recyclerview.widget.DiffUtil
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.base.adapter.SimpleRecyclerAdapter
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
@ -9,6 +10,9 @@ import io.legado.app.data.entities.Book
abstract class BaseBooksAdapter<VB : ViewBinding>(context: Context) : abstract class BaseBooksAdapter<VB : ViewBinding>(context: Context) :
SimpleRecyclerAdapter<Book, VB>(context) { SimpleRecyclerAdapter<Book, VB>(context) {
override val diffItemCallback: DiffUtil.ItemCallback<Book>
get() = BooksDiffCallBack()
fun notification(bookUrl: String) { fun notification(bookUrl: String) {
for (i in 0 until itemCount) { for (i in 0 until itemCount) {
getItem(i)?.let { getItem(i)?.let {

@ -4,27 +4,14 @@ import androidx.core.os.bundleOf
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
class BooksDiffCallBack(private val oldItems: List<Book>, private val newItems: List<Book>) : class BooksDiffCallBack() : DiffUtil.ItemCallback<Book>() {
DiffUtil.Callback() {
override fun getOldListSize(): Int { override fun areItemsTheSame(oldItem: Book, newItem: Book): Boolean {
return oldItems.size
}
override fun getNewListSize(): Int {
return newItems.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
return oldItem.name == newItem.name return oldItem.name == newItem.name
&& oldItem.author == newItem.author && oldItem.author == newItem.author
} }
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { override fun areContentsTheSame(oldItem: Book, newItem: Book): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
return when { return when {
oldItem.durChapterTime != newItem.durChapterTime -> false oldItem.durChapterTime != newItem.durChapterTime -> false
oldItem.name != newItem.name -> false oldItem.name != newItem.name -> false
@ -38,9 +25,7 @@ class BooksDiffCallBack(private val oldItems: List<Book>, private val newItems:
} }
} }
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? { override fun getChangePayload(oldItem: Book, newItem: Book): Any? {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
val bundle = bundleOf() val bundle = bundleOf()
if (oldItem.name != newItem.name) { if (oldItem.name != newItem.name) {
bundle.putString("name", newItem.name) bundle.putString("name", newItem.name)

@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.View import android.view.View
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -117,9 +116,7 @@ class BooksFragment : BaseFragment(R.layout.fragment_books),
3 -> list.sortedBy { it.order } 3 -> list.sortedBy { it.order }
else -> list.sortedByDescending { it.durChapterTime } else -> list.sortedByDescending { it.durChapterTime }
} }
val diffResult = DiffUtil booksAdapter.setItems(books)
.calculateDiff(BooksDiffCallBack(booksAdapter.getItems(), books))
booksAdapter.setItems(books, diffResult)
} }
} }
} }

@ -4,27 +4,13 @@ import android.os.Bundle
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import io.legado.app.data.entities.ReplaceRule import io.legado.app.data.entities.ReplaceRule
class DiffCallBack( class DiffCallBack : DiffUtil.ItemCallback<ReplaceRule>() {
private val oldItems: List<ReplaceRule>,
private val newItems: List<ReplaceRule>
) : DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
return oldItem.id == newItem.id
}
override fun getOldListSize(): Int { override fun areItemsTheSame(oldItem: ReplaceRule, newItem: ReplaceRule): Boolean {
return oldItems.size return oldItem.id == newItem.id
}
override fun getNewListSize(): Int {
return newItems.size
} }
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { override fun areContentsTheSame(oldItem: ReplaceRule, newItem: ReplaceRule): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
if (oldItem.name != newItem.name) { if (oldItem.name != newItem.name) {
return false return false
} }
@ -37,9 +23,7 @@ class DiffCallBack(
return true return true
} }
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? { override fun getChangePayload(oldItem: ReplaceRule, newItem: ReplaceRule): Any? {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
val payload = Bundle() val payload = Bundle()
if (oldItem.name != newItem.name) { if (oldItem.name != newItem.name) {
payload.putString("name", newItem.name) payload.putString("name", newItem.name)

@ -11,7 +11,6 @@ import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App import io.legado.app.App
@ -153,9 +152,7 @@ class ReplaceRuleActivity : VMBaseActivity<ActivityReplaceRuleBinding, ReplaceRu
if (dataInit) { if (dataInit) {
setResult(Activity.RESULT_OK) setResult(Activity.RESULT_OK)
} }
val diffResult = adapter.setItems(it)
DiffUtil.calculateDiff(DiffCallBack(ArrayList(adapter.getItems()), it))
adapter.setItems(it, diffResult)
dataInit = true dataInit = true
upCountView() upCountView()
}) })

@ -4,36 +4,19 @@ import android.os.Bundle
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssSource
class DiffCallBack( class DiffCallBack : DiffUtil.ItemCallback<RssSource>() {
private val oldItems: List<RssSource>,
private val newItems: List<RssSource>
) : DiffUtil.Callback() {
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { override fun areItemsTheSame(oldItem: RssSource, newItem: RssSource): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
return oldItem.sourceUrl == newItem.sourceUrl return oldItem.sourceUrl == newItem.sourceUrl
} }
override fun getOldListSize(): Int { override fun areContentsTheSame(oldItem: RssSource, newItem: RssSource): Boolean {
return oldItems.size
}
override fun getNewListSize(): Int {
return newItems.size
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
return oldItem.sourceName == newItem.sourceName return oldItem.sourceName == newItem.sourceName
&& oldItem.sourceGroup == newItem.sourceGroup && oldItem.sourceGroup == newItem.sourceGroup
&& oldItem.enabled == newItem.enabled && oldItem.enabled == newItem.enabled
} }
override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? { override fun getChangePayload(oldItem: RssSource, newItem: RssSource): Any? {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
val payload = Bundle() val payload = Bundle()
if (oldItem.sourceName != newItem.sourceName) { if (oldItem.sourceName != newItem.sourceName) {
payload.putString("name", newItem.sourceName) payload.putString("name", newItem.sourceName)

@ -11,7 +11,6 @@ import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import io.legado.app.App import io.legado.app.App
@ -209,9 +208,7 @@ class RssSourceActivity : VMBaseActivity<ActivityRssSourceBinding, RssSourceView
App.db.rssSourceDao.liveSearch("%$key%") App.db.rssSourceDao.liveSearch("%$key%")
} }
sourceLiveData?.observe(this, { sourceLiveData?.observe(this, {
val diffResult = DiffUtil adapter.setItems(it)
.calculateDiff(DiffCallBack(adapter.getItems(), it))
adapter.setItems(it, diffResult)
upCountView() upCountView()
}) })
} }

@ -6,6 +6,7 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.PopupMenu import android.widget.PopupMenu
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.ItemViewHolder
@ -22,6 +23,9 @@ class RssSourceAdapter(context: Context, val callBack: CallBack) :
SimpleRecyclerAdapter<RssSource, ItemRssSourceBinding>(context), SimpleRecyclerAdapter<RssSource, ItemRssSourceBinding>(context),
ItemTouchCallback.Callback { ItemTouchCallback.Callback {
override val diffItemCallback: DiffUtil.ItemCallback<RssSource>
get() = DiffCallBack()
private val selected = linkedSetOf<RssSource>() private val selected = linkedSetOf<RssSource>()
override fun getViewBinding(parent: ViewGroup): ItemRssSourceBinding { override fun getViewBinding(parent: ViewGroup): ItemRssSourceBinding {

Loading…
Cancel
Save