diff --git a/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadAdapter.kt b/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadAdapter.kt index bfbefe095..0541c491e 100644 --- a/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadAdapter.kt +++ b/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadAdapter.kt @@ -1,5 +1,6 @@ package com.chuckerteam.chucker.internal.ui.transaction +import android.content.Context import android.graphics.Bitmap import android.text.SpannableStringBuilder import android.text.Spanned @@ -8,6 +9,7 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView +import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.chuckerteam.chucker.R import com.chuckerteam.chucker.internal.support.highlightWithDefinedColors @@ -18,9 +20,16 @@ import com.chuckerteam.chucker.internal.support.highlightWithDefinedColors * performances when loading big payloads. */ internal class TransactionBodyAdapter( - private val bodyItems: List + private val bodyItems: List, + private val layoutManager: RecyclerView.LayoutManager, + val context: Context ) : RecyclerView.Adapter() { + private var linesWithHighlightsByIndex = mutableListOf() + private var currentHightLineIndex = 0 + private var currentSearchString: String? = null + private val scrollOffsetPx = context.dpToPx(20) + override fun onBindViewHolder(holder: TransactionPayloadViewHolder, position: Int) { holder.bind(bodyItems[position]) } @@ -54,10 +63,14 @@ internal class TransactionBodyAdapter( } internal fun highlightQueryWithColors(newText: String, backgroundColor: Int, foregroundColor: Int) { + linesWithHighlightsByIndex.clear() + currentHightLineIndex = 0 + currentSearchString = newText bodyItems.filterIsInstance() .withIndex() .forEach { (index, item) -> if (newText in item.line) { + linesWithHighlightsByIndex.add(index) item.line.clearSpans() item.line = item.line.toString() .highlightWithDefinedColors(newText, backgroundColor, foregroundColor) @@ -73,6 +86,38 @@ internal class TransactionBodyAdapter( } } + internal fun hasSearchResults(): Boolean = linesWithHighlightsByIndex.isNotEmpty() + + internal fun goToNextHighlightLine(backgroundColor: Int, foregroundColor: Int, hightlightBackgroundColor: Int, highlightForegroundColor: Int) { + val oldLineIdx = linesWithHighlightsByIndex[currentHightLineIndex] + val nextIdx = (++currentHightLineIndex).takeIf { it < linesWithHighlightsByIndex.size } ?: 0 + currentHightLineIndex = nextIdx + val newLineIdx = linesWithHighlightsByIndex[currentHightLineIndex] + + val lines = bodyItems.filterIsInstance() + + // Update old + lines[oldLineIdx].let { item -> + item.line.clearSpans() + item.line = item.line.toString() + .highlightWithDefinedColors(currentSearchString!!, backgroundColor, foregroundColor) + notifyItemChanged(oldLineIdx + 1) + } + + // set new + lines[newLineIdx].let { item -> + item.line.clearSpans() + item.line = item.line.toString() + .highlightWithDefinedColors(currentSearchString!!, hightlightBackgroundColor, highlightForegroundColor) + notifyItemChanged(newLineIdx + 1) + (layoutManager as? LinearLayoutManager)?.let { + it.scrollToPositionWithOffset(newLineIdx, scrollOffsetPx) + } ?: run { + layoutManager.scrollToPosition(newLineIdx) + } + } + } + internal fun resetHighlight() { bodyItems.filterIsInstance() .withIndex() @@ -128,3 +173,7 @@ internal sealed class TransactionPayloadItem { internal class BodyLineItem(var line: SpannableStringBuilder) : TransactionPayloadItem() internal class ImageItem(val image: Bitmap) : TransactionPayloadItem() } + +fun Context.dpToPx(dp: Int): Int { + return (dp * resources.displayMetrics.density).toInt() +} diff --git a/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadFragment.kt b/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadFragment.kt index 81923d2a4..7c8102972 100644 --- a/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadFragment.kt +++ b/library/src/main/java/com/chuckerteam/chucker/internal/ui/transaction/TransactionPayloadFragment.kt @@ -57,6 +57,9 @@ internal class TransactionPayloadFragment : private var backgroundSpanColor: Int = Color.YELLOW private var foregroundSpanColor: Int = Color.RED + private var highlightBackgroundSpanColor: Int = Color.BLUE + private var hightlightForegroundSpanColor: Int = Color.WHITE + private var type: Int = 0 private lateinit var viewModel: TransactionViewModel @@ -140,6 +143,8 @@ internal class TransactionPayloadFragment : super.onAttach(context) backgroundSpanColor = ContextCompat.getColor(context, R.color.chucker_background_span_color) foregroundSpanColor = ContextCompat.getColor(context, R.color.chucker_foreground_span_color) + highlightBackgroundSpanColor = ContextCompat.getColor(context, R.color.chucker_highlight_background_span_color) + hightlightForegroundSpanColor = ContextCompat.getColor(context, R.color.chucker_highlight_foreground_span_color) } @RequiresApi(Build.VERSION_CODES.KITKAT) @@ -174,7 +179,14 @@ internal class TransactionPayloadFragment : } } - override fun onQueryTextSubmit(query: String): Boolean = false + override fun onQueryTextSubmit(query: String): Boolean { + val adapter = (transactionContentList.adapter as TransactionBodyAdapter) + if (adapter.hasSearchResults()) { + adapter.goToNextHighlightLine(backgroundSpanColor, foregroundSpanColor, highlightBackgroundSpanColor, hightlightForegroundSpanColor) + return true + } + return false + } override fun onQueryTextChange(newText: String): Boolean { val adapter = (transactionContentList.adapter as TransactionBodyAdapter) @@ -248,7 +260,7 @@ internal class TransactionPayloadFragment : val recyclerView: RecyclerView? = fragment.view?.findViewById(R.id.transaction_content) progressBar?.visibility = View.INVISIBLE recyclerView?.visibility = View.VISIBLE - recyclerView?.adapter = TransactionBodyAdapter(result) + recyclerView?.adapter = TransactionBodyAdapter(result, recyclerView?.layoutManager!!, recyclerView.context) } } diff --git a/library/src/main/res/values/colors.xml b/library/src/main/res/values/colors.xml index 15b7137f8..ee0cb93be 100644 --- a/library/src/main/res/values/colors.xml +++ b/library/src/main/res/values/colors.xml @@ -21,4 +21,7 @@ #ffffff00 #ffff0000 + + #ff0000ff + #ffffffff \ No newline at end of file