From cc0d264791d7e9ebd996cac23894f00c9355a2d6 Mon Sep 17 00:00:00 2001 From: Christian Schneppe Date: Wed, 2 May 2018 20:59:08 +0200 Subject: highlight search term in search results --- .../de/pixart/messenger/ui/SearchActivity.java | 2 + .../messenger/ui/adapter/MessageAdapter.java | 9 +++++ .../de/pixart/messenger/utils/StylingHelper.java | 43 ++++++++++++++++++++++ 3 files changed, 54 insertions(+) (limited to 'src/main') diff --git a/src/main/java/de/pixart/messenger/ui/SearchActivity.java b/src/main/java/de/pixart/messenger/ui/SearchActivity.java index 54c5ef5e4..7c43bf37c 100644 --- a/src/main/java/de/pixart/messenger/ui/SearchActivity.java +++ b/src/main/java/de/pixart/messenger/ui/SearchActivity.java @@ -204,6 +204,7 @@ public class SearchActivity extends XmppActivity implements TextWatcher, OnSearc } else { MessageSearchTask.cancelRunningTasks(); this.messages.clear(); + messageListAdapter.setHighlightedTerm(null); messageListAdapter.notifyDataSetChanged(); changeBackground(false, false); } @@ -213,6 +214,7 @@ public class SearchActivity extends XmppActivity implements TextWatcher, OnSearc public void onSearchResultsAvailable(String term, List messages) { runOnUiThread(() -> { this.messages.clear(); + messageListAdapter.setHighlightedTerm(term); DateSeparator.addAll(messages); this.messages.addAll(messages); messageListAdapter.notifyDataSetChanged(); diff --git a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java index ad9bb8f4a..37eb00b76 100644 --- a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java +++ b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java @@ -109,6 +109,8 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie + "|(?:\\%[a-fA-F0-9]{2}))+"); boolean isResendable = false; + private String highlightedText = null; + private static final Linkify.TransformFilter WEBURL_TRANSFORM_FILTER = (matcher, url) -> { if (url == null) { return null; @@ -595,6 +597,9 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie } } StylingHelper.format(body, viewHolder.messageBody.getCurrentTextColor()); + if (highlightedText != null) { + StylingHelper.highlight(activity, body, highlightedText, StylingHelper.isDarkText(viewHolder.messageBody)); + } Linkify.addLinks(body, XMPP_PATTERN, "xmpp", XMPPURI_MATCH_FILTER, null); Linkify.addLinks(body, Patterns.AUTOLINK_WEB_URL, "http", WEBURL_MATCH_FILTER, WEBURL_TRANSFORM_FILTER); Linkify.addLinks(body, GeoHelper.GEO_URI, "geo"); @@ -1156,6 +1161,10 @@ public class MessageAdapter extends ArrayAdapter implements CopyTextVie } } + public void setHighlightedTerm(String term) { + this.highlightedText = term; + } + public interface OnQuoteListener { void onQuote(String text); } diff --git a/src/main/java/de/pixart/messenger/utils/StylingHelper.java b/src/main/java/de/pixart/messenger/utils/StylingHelper.java index 1f553b827..21e074603 100644 --- a/src/main/java/de/pixart/messenger/utils/StylingHelper.java +++ b/src/main/java/de/pixart/messenger/utils/StylingHelper.java @@ -29,22 +29,28 @@ package de.pixart.messenger.utils; +import android.content.Context; import android.graphics.Color; import android.graphics.Typeface; import android.support.annotation.ColorInt; +import android.support.v4.content.ContextCompat; import android.text.Editable; import android.text.ParcelableSpan; +import android.text.SpannableString; import android.text.Spanned; import android.text.TextWatcher; +import android.text.style.BackgroundColorSpan; import android.text.style.ForegroundColorSpan; import android.text.style.StrikethroughSpan; import android.text.style.StyleSpan; import android.text.style.TypefaceSpan; import android.widget.EditText; +import android.widget.TextView; import java.util.Arrays; import java.util.List; +import de.pixart.messenger.R; import de.pixart.messenger.entities.Message; import de.pixart.messenger.ui.text.QuoteSpan; @@ -85,6 +91,24 @@ public class StylingHelper { format(editable, end, editable.length() - 1, textColor); } + public static void highlight(final Context context, final Editable editable, String needle, boolean dark) { + final int length = needle.length(); + String string = editable.toString(); + int start = indexOfIgnoreCase(string, needle, 0); + while (start != -1) { + int end = start + length; + editable.setSpan(new BackgroundColorSpan(ContextCompat.getColor(context, dark ? R.color.deep_purple_a100 : R.color.deep_purple_a200)), start, end, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE); + editable.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, dark ? R.color.black87 : R.color.white)), start, end, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE); + start = indexOfIgnoreCase(string, needle, start + length); + } + + } + + public static boolean isDarkText(TextView textView) { + int argb = textView.getCurrentTextColor(); + return Color.red(argb) + Color.green(argb) + Color.blue(argb) == 0; + } + private static ParcelableSpan createSpanForStyle(ImStyleParser.Style style) { switch (style.getKeyword()) { case "*": @@ -114,6 +138,25 @@ public class StylingHelper { return Color.argb(Math.round(Color.alpha(c) * 0.6f), Color.red(c), Color.green(c), Color.blue(c)); } + private static int indexOfIgnoreCase(final String haystack, final String needle, final int start) { + if (haystack == null || needle == null) { + return -1; + } + final int endLimit = haystack.length() - needle.length() + 1; + if (start > endLimit) { + return -1; + } + if (needle.length() == 0) { + return start; + } + for (int i = start; i < endLimit; i++) { + if (haystack.regionMatches(true, i, needle, 0, needle.length())) { + return i; + } + } + return -1; + } + public static class MessageEditorStyler implements TextWatcher { private final EditText mEditText; -- cgit v1.2.3