优化搜索

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.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<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 {
return ItemSearchBinding.inflate(inflater, parent, false)

@ -62,12 +62,8 @@ class SearchViewModel(application: Application) : BaseViewModel(application),
}
override fun onSearchSuccess(searchBooks: ArrayList<SearchBook>) {
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<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
private fun mergeItems(scope: CoroutineScope, newDataS: List<SearchBook>) {
private fun mergeItems(scope: CoroutineScope, newDataS: List<SearchBook>, precision: Boolean) {
if (newDataS.isNotEmpty()) {
val copyDataS = ArrayList(searchBooks)
val searchBooksAdd = ArrayList<SearchBook>()
if (copyDataS.size == 0) {
copyDataS.addAll(newDataS)
} else {
//存在
newDataS.forEach { item ->
val prevData = ArrayList(searchBooks)
val precisionData = arrayListOf<SearchBook>()
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()
}
}

Loading…
Cancel
Save