I'm developing a simple search box in my application, and I want to highlight multiple words in one sentence.
I use SpannableString to add multiple span in one sentence. Here the function a wrote
private CharSequence highlightText(String text, String query) {
if (query != null && !query.isEmpty()) {
Spannable spannable = new SpannableString(text);
ForegroundColorSpan highlightSpan = new ForegroundColorSpan(Color.BLUE);
String[] queryParts = query.split(" ");
for (String queryPart : queryParts) {
int startPos = text.toLowerCase(Locale.US).indexOf(queryPart.toLowerCase(Locale.US));
int endPos = startPos + queryPart.length();
if (startPos != -1) {
Log.d(TAG, "find: '" + queryPart + "' in '" + text + "' (" + startPos + ")");
spannable.setSpan(highlightSpan, startPos, endPos, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return spannable;
} else {
return text;
}
}
When I cal this function with
TextView spannableTest = findViewById(R.id.spannable_test);
spannableTest.setText(highlightText(
"Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
"ipsum consect"));
I got this logs
D/SPAN: find: 'ipsum' in 'Lorem ipsum dolor sit amet, consectetur adipisicing elit.' (6)
D/SPAN: find: 'consect' in 'Lorem ipsum dolor sit amet, consectetur adipisicing elit.' (28)
But on result screen only the last occurence is realy highlighted
@pskink pointed I should move ForegroundColorSpan highlightSpan = new ForegroundColorSpan(Color.BLUE);
to for
loop.
Add this file to your project:RichTextView.java
package com.outpace.expert.utility;
import android.graphics.Typeface;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.URLSpan;
import android.view.View;
/**
* Created by Deep Patel on 19-11-16
*/
//.setText(text, TextView.BufferType.SPANNABLE); to textView if not work
public class RichTextView extends SpannableString {
private String syntax;
public RichTextView(String syntax) {
super(syntax);
this.syntax = syntax;
}
public RichTextView setTextColor(String word, int color) {
setSpan(new ForegroundColorSpan(color), syntax.indexOf(word), syntax.indexOf(word) + word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return this;
}
public RichTextView setSize(String word, float howMuch) {
setSpan(new RelativeSizeSpan(howMuch), syntax.indexOf(word), syntax.indexOf(word) + word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return this;
}
public RichTextView setStrikeOut(String word) {
setSpan(new StrikethroughSpan(), syntax.indexOf(word), syntax.indexOf(word) + word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return this;
}
public RichTextView setUrl(String word, String redirectUrl) {
setSpan(new URLSpan(redirectUrl), syntax.indexOf(word), syntax.indexOf(word) + word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return this;
}
public RichTextView setBold(String word) {
StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
setSpan(boldSpan, syntax.indexOf(word), syntax.indexOf(word) + word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return this;
}
//setMovementMethod(LinkMovementMethod.getInstance()); after or before call
public RichTextView setClickable(String word, final setOnLinkClickListener listener) {
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.onLinkClicked();
}
}
};
setSpan(clickableSpan, syntax.indexOf(word), syntax.indexOf(word) + word.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return this;
}
public interface setOnLinkClickListener {
void onLinkClicked();
}
}
Here is how to use:
String data = model.getMessage().replace("{from_name}", model.getFromUser()); // String to display
tvNotificationText.setText(new RichTextView(data)
.setBold(model.getFromUser()) // bold
.setTextColor(model.getFromUser(), ContextCompat.getColor(mContext, R.color.textPrimary))); // set text color for specific string
There are other spanning options available please explore and get the best fit solution!
Happy Coding !!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With