优化搜索

pull/737/head
gedoor 4 years ago
parent b5a274040d
commit 4ddf6599aa
  1. 44
      app/src/main/java/io/legado/app/ui/book/search/SearchAdapter.kt
  2. 119
      app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt

@ -3,9 +3,10 @@ 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.DiffRecyclerAdapter
import io.legado.app.base.adapter.ItemViewHolder 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.data.entities.SearchBook
import io.legado.app.databinding.ItemSearchBinding import io.legado.app.databinding.ItemSearchBinding
import io.legado.app.utils.gone import io.legado.app.utils.gone
@ -13,7 +14,46 @@ import io.legado.app.utils.visible
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
class SearchAdapter(context: Context, val callBack: CallBack) : class SearchAdapter(context: Context, val callBack: CallBack) :
RecyclerAdapter<SearchBook, ItemSearchBinding>(context) { DiffRecyclerAdapter<SearchBook, ItemSearchBinding>(context) {
override val diffItemCallback: DiffUtil.ItemCallback<SearchBook>
get() = object : DiffUtil.ItemCallback<SearchBook>() {
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 { override fun getViewBinding(parent: ViewGroup): ItemSearchBinding {
return ItemSearchBinding.inflate(inflater, parent, false) return ItemSearchBinding.inflate(inflater, parent, false)

@ -62,12 +62,8 @@ class SearchViewModel(application: Application) : BaseViewModel(application),
} }
override fun onSearchSuccess(searchBooks: ArrayList<SearchBook>) { override fun onSearchSuccess(searchBooks: ArrayList<SearchBook>) {
if (context.getPrefBoolean(PreferKey.precisionSearch)) { val precision = context.getPrefBoolean(PreferKey.precisionSearch)
precisionSearch(this, searchBooks) mergeItems(this, searchBooks, precision)
} else {
App.db.searchBookDao.insert(*searchBooks.toTypedArray())
mergeItems(this, searchBooks)
}
} }
override fun onSearchFinish() { override fun onSearchFinish() {
@ -80,98 +76,59 @@ class SearchViewModel(application: Application) : BaseViewModel(application),
isLoading = false isLoading = false
} }
/**
* 精确搜索处理
*/
private fun precisionSearch(scope: CoroutineScope, searchBooks: List<SearchBook>) {
val books = arrayListOf<SearchBook>()
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 @Synchronized
private fun mergeItems(scope: CoroutineScope, newDataS: List<SearchBook>) { private fun mergeItems(scope: CoroutineScope, newDataS: List<SearchBook>, precision: Boolean) {
if (newDataS.isNotEmpty()) { if (newDataS.isNotEmpty()) {
val copyDataS = ArrayList(searchBooks) val prevData = ArrayList(searchBooks)
val searchBooksAdd = ArrayList<SearchBook>() val precisionData = arrayListOf<SearchBook>()
if (copyDataS.size == 0) { prevData.forEach {
copyDataS.addAll(newDataS) if (!scope.isActive) return
} else { if (it.name == searchKey || it.author == searchKey) {
//存在 precisionData.add(it)
newDataS.forEach { item -> }
}
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 var hasSame = false
for (searchBook in copyDataS) { precisionData.forEach { pBook ->
if (item.name == searchBook.name if (!scope.isActive) return
&& item.author == searchBook.author if (pBook.name == nBook.name && pBook.author == nBook.author) {
) { pBook.addOrigin(nBook.origin)
hasSame = true hasSame = true
searchBook.addOrigin(item.origin)
break
} }
} }
if (!hasSame) { if (!hasSame) {
searchBooksAdd.add(item) precisionData.add(nBook)
} }
} } else if (!precision) {
//添加 var hasSame = false
searchBooksAdd.forEach { item -> prevData.forEach { pBook ->
if (searchKey == item.name) { if (!scope.isActive) return
for ((index, searchBook) in copyDataS.withIndex()) { if (pBook.name == nBook.name && pBook.author == nBook.author) {
if (searchKey != searchBook.name) { pBook.addOrigin(nBook.origin)
copyDataS.add(index, item) hasSame = true
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 {
copyDataS.add(item)
} }
} if (!hasSame) {
} prevData.add(nBook)
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
}
} }
} else {
0
} }
} }
if (!scope.isActive) return if (!scope.isActive) return
searchBooks = copyDataS precisionData.sortByDescending { it.origins.size }
if (!scope.isActive) return
if (!precision) {
precisionData.addAll(prevData)
}
searchBooks = precisionData
upAdapter() upAdapter()
} }
} }

Loading…
Cancel
Save