全文搜索界面优化 #262
This commit is contained in:
@@ -61,13 +61,7 @@ class SearchContentActivity :
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
// val bbg = bottomBackground
|
||||
// val btc = getPrimaryTextColor(ColorUtils.isColorLight(bbg))
|
||||
// binding.llSearchBaseInfo.setBackgroundColor(bbg)
|
||||
binding.llSearchBaseInfo.applyNavigationBarPadding()
|
||||
// binding.tvCurrentSearchInfo.setTextColor(btc)
|
||||
// binding.ivSearchContentTop.setColorFilter(btc)
|
||||
// binding.ivSearchContentBottom.setColorFilter(btc)
|
||||
val searchResultList = IntentData.get<List<SearchResult>>("searchResultList")
|
||||
val position = intent.getIntExtra("searchResultIndex", 0)
|
||||
val noSearchResult = searchResultList == null
|
||||
@@ -143,7 +137,6 @@ class SearchContentActivity :
|
||||
|
||||
private fun initRecyclerView() {
|
||||
binding.recyclerView.layoutManager = mLayoutManager
|
||||
binding.recyclerView.addItemDecoration(VerticalDivider(this))
|
||||
binding.recyclerView.adapter = adapter
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package io.legado.app.ui.book.searchContent
|
||||
|
||||
//import io.legado.app.lib.theme.accentColor
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup
|
||||
import io.legado.app.base.adapter.ItemViewHolder
|
||||
import io.legado.app.base.adapter.RecyclerAdapter
|
||||
import io.legado.app.databinding.ItemSearchListBinding
|
||||
import io.legado.app.utils.hexString
|
||||
import io.legado.app.utils.themeColor
|
||||
|
||||
|
||||
class SearchContentAdapter(context: Context, val callback: Callback) :
|
||||
RecyclerAdapter<SearchResult, ItemSearchListBinding>(context) {
|
||||
|
||||
val textColor = context.themeColor(com.google.android.material.R.attr.colorOnSurface).hexString.substring(2)
|
||||
val accentColor =
|
||||
context.themeColor(androidx.appcompat.R.attr.colorPrimary).hexString.substring(2)
|
||||
private val textColorInt = context.themeColor(com.google.android.material.R.attr.colorOnSurface)
|
||||
private val accentColorInt = context.themeColor(androidx.appcompat.R.attr.colorPrimary)
|
||||
private val bgColorInt = context.themeColor(com.google.android.material.R.attr.colorSecondaryContainer)
|
||||
|
||||
override fun getViewBinding(parent: ViewGroup): ItemSearchListBinding {
|
||||
return ItemSearchListBinding.inflate(inflater, parent, false)
|
||||
@@ -30,14 +28,19 @@ class SearchContentAdapter(context: Context, val callback: Callback) :
|
||||
binding.run {
|
||||
val isDur = callback.durChapterIndex() == item.chapterIndex
|
||||
if (payloads.isEmpty()) {
|
||||
tvSearchResult.text = item.getHtmlCompat(textColor, accentColor)
|
||||
tvSearchResult.paint.isFakeBoldText = isDur
|
||||
tvTitle.text = item.getTitleSpannable(textColorInt)
|
||||
tvContent.text = item.getContentSpannable(textColorInt, accentColorInt, bgColorInt)
|
||||
|
||||
cdRoot.setCardBackgroundColor(
|
||||
if (isDur) context.themeColor(com.google.android.material.R.attr.colorSurfaceContainer)
|
||||
else context.themeColor(com.google.android.material.R.attr.colorSurface)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerListener(holder: ItemViewHolder, binding: ItemSearchListBinding) {
|
||||
holder.itemView.setOnClickListener {
|
||||
binding.cdRoot.setOnClickListener {
|
||||
getItem(holder.layoutPosition)?.let {
|
||||
if (it.query.isNotBlank()) callback.openSearchResult(it, holder.layoutPosition)
|
||||
}
|
||||
@@ -48,4 +51,4 @@ class SearchContentAdapter(context: Context, val callback: Callback) :
|
||||
fun openSearchResult(searchResult: SearchResult, index: Int)
|
||||
fun durChapterIndex(): Int
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
package io.legado.app.ui.book.searchContent
|
||||
|
||||
import android.text.Spanned
|
||||
import androidx.core.text.HtmlCompat
|
||||
import android.graphics.Typeface
|
||||
import android.text.Spannable
|
||||
import android.text.SpannableString
|
||||
import android.text.SpannableStringBuilder
|
||||
import android.text.style.BackgroundColorSpan
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.text.style.StyleSpan
|
||||
import android.text.style.UnderlineSpan
|
||||
import io.legado.app.help.config.AppConfig
|
||||
|
||||
data class SearchResult(
|
||||
@@ -17,44 +23,48 @@ data class SearchResult(
|
||||
val queryIndexInChapter: Int = 0
|
||||
) {
|
||||
|
||||
fun getHtmlCompat(textColor: String, accentColor: String): Spanned {
|
||||
return if (query.isNotBlank()) {
|
||||
val queryIndexInSurrounding = resultText.indexOf(query)
|
||||
val leftString = resultText.substring(0, queryIndexInSurrounding)
|
||||
val rightString =
|
||||
resultText.substring(queryIndexInSurrounding + query.length, resultText.length)
|
||||
// 检查是否为墨水屏模式
|
||||
val html = if (AppConfig.isEInkMode) {
|
||||
// 墨水屏模式:使用下划线
|
||||
buildString {
|
||||
append("<u>${chapterTitle}</u>")
|
||||
append("<br>")
|
||||
append(leftString)
|
||||
append("<u>${query}</u>")
|
||||
append(rightString)
|
||||
}
|
||||
} else {
|
||||
// 普通模式:使用颜色
|
||||
buildString {
|
||||
append(chapterTitle.colorTextForHtml(accentColor))
|
||||
append("<br>")
|
||||
append(leftString.colorTextForHtml(textColor))
|
||||
append(query.colorTextForHtml(accentColor))
|
||||
append(rightString.colorTextForHtml(textColor))
|
||||
}
|
||||
fun getTitleSpannable(accentColor: Int): SpannableString {
|
||||
return if (AppConfig.isEInkMode) {
|
||||
SpannableString(chapterTitle).apply {
|
||||
setSpan(UnderlineSpan(), 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||
} else {
|
||||
val html = if (AppConfig.isEInkMode) {
|
||||
resultText
|
||||
} else {
|
||||
resultText.colorTextForHtml(textColor)
|
||||
SpannableString(chapterTitle).apply {
|
||||
setSpan(ForegroundColorSpan(accentColor), 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.colorTextForHtml(textColor: String) =
|
||||
"<font color=#${textColor}>$this</font>"
|
||||
fun getContentSpannable(textColor: Int, accentColor: Int, bgColor: Int): SpannableStringBuilder {
|
||||
val spannable = SpannableStringBuilder(resultText)
|
||||
|
||||
}
|
||||
if (query.isNotBlank()) {
|
||||
var searchStart = 0
|
||||
while (true) {
|
||||
val start = resultText.indexOf(query, searchStart, ignoreCase = true)
|
||||
if (start == -1) break
|
||||
val end = start + query.length
|
||||
|
||||
if (AppConfig.isEInkMode) {
|
||||
spannable.setSpan(UnderlineSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
} else {
|
||||
// 字体加粗
|
||||
spannable.setSpan(StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
// 字体颜色
|
||||
spannable.setSpan(ForegroundColorSpan(accentColor), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
// 背景色
|
||||
spannable.setSpan(BackgroundColorSpan(bgColor), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
|
||||
searchStart = end
|
||||
}
|
||||
}
|
||||
|
||||
// 设置整体字体颜色(正文)
|
||||
if (!AppConfig.isEInkMode) {
|
||||
spannable.setSpan(ForegroundColorSpan(textColor), 0, spannable.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
|
||||
return spannable
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user