Android - Highlight a Word In a TextView?

2019-01-21 05:53发布

问题:

I have a database search query which search in the database for a word entered by the user and return a Cursor.

In my ListActivity, I have a ListView which will hold the items (the Cursor items). The ListView items layout is basically a TextView. I mean, the ListView will be a list of TextView's.

What I want is to highlight the search term wherever it appears in the TextView. I mean by highlighting: different color or different background color or anything makes it different than the rest of the text.

Is this possible? and how?

Update:

cursor = myDbHelper.search(term);  //term: a word entered by the user.
cursor.moveToFirst();
String[] columns = {cursor.getColumnName(1)}; 
int[] columnsLayouts = {R.id.item_title}; //item_title: the TextView holding the one raw
ca = new SimpleCursorAdapter(this.getBaseContext(), R.layout.items_layout, cursor,columns , columnsLayouts);
lv = getListView();
lv.setAdapter(ca);

For @Shailendra: The search() method will return some titles. I want to highlight the words in those titles that matches the term word. I hope this is clear now.

回答1:

insert HTML code for color around word and set it to your textView .

like

String newString = oldString.replaceAll(textToHighlight, "<font color='red'>"+textToHighlight+"</font>");
textView.setText(Html.fromHtml(newString));


回答2:

TextView textView = (TextView)findViewById(R.id.mytextview01);

//use a loop to change text color
Spannable WordtoSpan = new SpannableString("partial colored text");        
WordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 2, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(WordtoSpan);

The numbers 2 and 4 are start/stop indexes for the coloring of the text, in this example "rti" would be colored.

So you would basically just find the starting index of your searching word in the title:

int startIndex = titleText.indexOf(term);
int stopIndex = startIndex + term.length();

and then replace the numbers 2 and 4 with the indexes and "partial colored text" with your title string.

source: https://stackoverflow.com/a/10279703/2160827



回答3:

I haven't done it but this looks promising:

http://developer.android.com/reference/android/text/SpannableString.html
http://developer.android.com/guide/topics/resources/string-resource.html

public final void setText (CharSequence text)

Since: API Level 1 Sets the string value of the TextView. TextView does not accept HTML-like formatting, which you can do with text strings in XML resource files. To style your strings, attach android.text.style.* objects to a SpannableString, or see the Available Resource Types documentation for an example of setting formatted text in the XML resource file.

http://developer.android.com/reference/android/widget/TextView.html



回答4:

I know it's old question but i have created a method to highlight a repeated-word in string\paragraph.

private Spannable highlight(int color, Spannable original, String word) {
    String normalized = Normalizer.normalize(original, Normalizer.Form.NFD)
            .replaceAll("\\p{InCombiningDiacriticalMarks}+", "");

    int start = normalized.indexOf(word);
    if (start < 0) {
        return original;
    } else {
        Spannable highlighted = new SpannableString(original);
        while (start >= 0) {
            int spanStart = Math.min(start, original.length());
            int spanEnd = Math.min(start+word.length(), original.length());

            highlighted.setSpan(new ForegroundColorSpan(color), spanStart,
                    spanEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

            start = normalizedText.indexOf(word, spanEnd);
        }
        return highlighted;
    }
}

usage:

textView.setText(highlight(primaryColor, textAll, wordToHighlight));


回答5:

Try this library Android TextHighlighter.

Implementations

TextView.setText() gets a parameter as Spannable not only CharacterSequence. SpannableString has a method setSpan() which allows applying styles.

See list of direct subclass form CharacterStyle https://developer.android.com/reference/android/text/style/CharacterStyle.html

  • example of giving background color and foreground color for word "Hello" in "Hello, World"
Spannable spannable = new SpannableString("Hello, World");
// setting red foreground color
ForegroundSpan fgSpan = new ForegroundColorSpan(Color.red);
// setting blue background color
BackgroundSpan bgSpan = new BackgroundColorSPan(Color.blue);

// setSpan requires start and end index
// in our case, it's 0 and 5
// You can directly set fgSpan or bgSpan, however,
// to reuse defined CharacterStyle, use CharacterStyle.wrap()
spannable.setSpan(CharacterStyle.wrap(fgSpan), 0, 5, 0);
spannable.setSpan(CharacterStyle.wrap(bgSpan), 0, 5, 0);

// apply spannableString on textview
textView.setText(spannable);


回答6:

You do so in xml strings if your strings are static

<string name="my_text">This text is <font color='red'>red here</font></string>


回答7:

More Easy Way

You can use Spannable class for highlighting/formatting part of Text.

textView.setText("Hello, I am Awesome, Most Awesome"); // set text first
setHighLightedText(textView, "a"); // highlight all `a` in TextView

Here is the method.

 /**
     * use this method to highlight a text in TextView
     *
     * @param tv              TextView or Edittext or Button (or derived from TextView)
     * @param textToHighlight Text to highlight
     */
    public void setHighLightedText(TextView tv, String textToHighlight) {
        String tvt = tv.getText().toString();
        int ofe = tvt.indexOf(textToHighlight, 0);
        Spannable wordToSpan = new SpannableString(tv.getText());
        for (int ofs = 0; ofs < tvt.length() && ofe != -1; ofs = ofe + 1) {
            ofe = tvt.indexOf(textToHighlight, ofs);
            if (ofe == -1)
                break;
            else {
                // set color here
                wordToSpan.setSpan(new BackgroundColorSpan(0xFFFFFF00), ofe, ofe + textToHighlight.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                tv.setText(wordToSpan, TextView.BufferType.SPANNABLE);
            }
        }
    }

You can check this answer for clickable highlighted text.