diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchAdapter.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchAdapter.kt index cd2221888..22605747d 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchAdapter.kt @@ -3,9 +3,10 @@ package io.legado.app.ui.book.search import android.content.Context import android.os.Bundle import android.view.ViewGroup +import androidx.recyclerview.widget.DiffUtil import io.legado.app.R +import io.legado.app.base.adapter.DiffRecyclerAdapter import io.legado.app.base.adapter.ItemViewHolder -import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.data.entities.SearchBook import io.legado.app.databinding.ItemSearchBinding import io.legado.app.utils.gone @@ -13,7 +14,46 @@ import io.legado.app.utils.visible import org.jetbrains.anko.sdk27.listeners.onClick class SearchAdapter(context: Context, val callBack: CallBack) : - RecyclerAdapter(context) { + DiffRecyclerAdapter(context) { + + override val diffItemCallback: DiffUtil.ItemCallback + get() = object : DiffUtil.ItemCallback() { + + override fun areItemsTheSame(oldItem: SearchBook, newItem: SearchBook): Boolean { + return when { + oldItem.name != newItem.name -> false + oldItem.author != newItem.author -> false + else -> true + } + } + + override fun areContentsTheSame(oldItem: SearchBook, newItem: SearchBook): Boolean { + return when { + oldItem.origins.size != newItem.origins.size -> false + oldItem.coverUrl != newItem.coverUrl -> false + oldItem.kind != newItem.kind -> false + oldItem.latestChapterTitle != newItem.latestChapterTitle -> false + oldItem.intro != newItem.intro -> false + else -> true + } + } + + override fun getChangePayload(oldItem: SearchBook, newItem: SearchBook): Any? { + val payload = Bundle() + if (oldItem.name != newItem.name) payload.putString("name", newItem.name) + if (oldItem.author != newItem.author) payload.putString("author", newItem.author) + if (oldItem.origins.size != newItem.origins.size) + payload.putInt("origins", newItem.origins.size) + if (oldItem.coverUrl != newItem.coverUrl) payload.putString("cover", newItem.coverUrl) + if (oldItem.kind != newItem.kind) payload.putString("kind", newItem.kind) + if (oldItem.latestChapterTitle != newItem.latestChapterTitle) + payload.putString("last", newItem.latestChapterTitle) + if (oldItem.intro != newItem.intro) payload.putString("intro", newItem.intro) + if (payload.isEmpty) return null + return payload + } + + } override fun getViewBinding(parent: ViewGroup): ItemSearchBinding { return ItemSearchBinding.inflate(inflater, parent, false) diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt index deb1ab453..431d1ff2c 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt @@ -62,12 +62,8 @@ class SearchViewModel(application: Application) : BaseViewModel(application), } override fun onSearchSuccess(searchBooks: ArrayList) { - if (context.getPrefBoolean(PreferKey.precisionSearch)) { - precisionSearch(this, searchBooks) - } else { - App.db.searchBookDao.insert(*searchBooks.toTypedArray()) - mergeItems(this, searchBooks) - } + val precision = context.getPrefBoolean(PreferKey.precisionSearch) + mergeItems(this, searchBooks, precision) } override fun onSearchFinish() { @@ -80,98 +76,59 @@ class SearchViewModel(application: Application) : BaseViewModel(application), isLoading = false } - /** - * 精确搜索处理 - */ - private fun precisionSearch(scope: CoroutineScope, searchBooks: List) { - val books = arrayListOf() - searchBooks.forEach { searchBook -> - if (searchBook.name.contains(searchKey, true) - || searchBook.author.contains(searchKey, true) - ) books.add(searchBook) - } - App.db.searchBookDao.insert(*books.toTypedArray()) - if (scope.isActive) { - mergeItems(scope, books) - } - } - /** * 合并搜索结果并排序 */ @Synchronized - private fun mergeItems(scope: CoroutineScope, newDataS: List) { + private fun mergeItems(scope: CoroutineScope, newDataS: List, precision: Boolean) { if (newDataS.isNotEmpty()) { - val copyDataS = ArrayList(searchBooks) - val searchBooksAdd = ArrayList() - if (copyDataS.size == 0) { - copyDataS.addAll(newDataS) - } else { - //存在 - newDataS.forEach { item -> + val prevData = ArrayList(searchBooks) + val precisionData = arrayListOf() + prevData.forEach { + if (!scope.isActive) return + if (it.name == searchKey || it.author == searchKey) { + precisionData.add(it) + } + } + repeat(precisionData.size) { + if (!scope.isActive) return + prevData.removeAt(0) + } + newDataS.forEach { nBook -> + if (!scope.isActive) return + if (nBook.name == searchKey || nBook.author == searchKey) { var hasSame = false - for (searchBook in copyDataS) { - if (item.name == searchBook.name - && item.author == searchBook.author - ) { + precisionData.forEach { pBook -> + if (!scope.isActive) return + if (pBook.name == nBook.name && pBook.author == nBook.author) { + pBook.addOrigin(nBook.origin) hasSame = true - searchBook.addOrigin(item.origin) - break } } if (!hasSame) { - searchBooksAdd.add(item) + precisionData.add(nBook) } - } - //添加 - searchBooksAdd.forEach { item -> - if (searchKey == item.name) { - for ((index, searchBook) in copyDataS.withIndex()) { - if (searchKey != searchBook.name) { - copyDataS.add(index, item) - break - } - } - } else if (searchKey == item.author) { - for ((index, searchBook) in copyDataS.withIndex()) { - if (searchKey != searchBook.name && searchKey == searchBook.author) { - copyDataS.add(index, item) - break - } + } else if (!precision) { + var hasSame = false + prevData.forEach { pBook -> + if (!scope.isActive) return + if (pBook.name == nBook.name && pBook.author == nBook.author) { + pBook.addOrigin(nBook.origin) + hasSame = true } - } else { - copyDataS.add(item) } - } - } - if (!scope.isActive) return - searchBooks.sortWith { o1, o2 -> - if (o1.name == searchKey && o2.name != searchKey) { - 1 - } else if (o1.name != searchKey && o2.name == searchKey) { - -1 - } else if (o1.author == searchKey && o2.author != searchKey) { - 1 - } else if (o1.author != searchKey && o2.author == searchKey) { - -1 - } else if (o1.name == o2.name) { - when { - o1.origins.size > o2.origins.size -> { - 1 - } - o1.origins.size < o2.origins.size -> { - -1 - } - else -> { - 0 - } + if (!hasSame) { + prevData.add(nBook) } - } else { - 0 } } if (!scope.isActive) return - searchBooks = copyDataS + precisionData.sortByDescending { it.origins.size } + if (!scope.isActive) return + if (!precision) { + precisionData.addAll(prevData) + } + searchBooks = precisionData upAdapter() } }