Android - Highlight a Word In a TextView?

前提是你 提交于 2019-12-17 17:31:20

问题


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 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));



回答4:


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




回答5:


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.




回答6:


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);



回答7:


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>



回答8:


I know this thread is old, but just in case anyone is looking to highlight strings in a textview, I have created a library that does exactly this. This is my first answer to a question on stack overflow, as I have just joined, hopefully it's formatted properly and relevant. It uses SpannableString and will locate all occurrences of a string you specify. Additionally, a custom ClickableSpan is built in giving you the option to set up listeners for text clicked if desired.

Linker

Lightweight android library for highlighting Strings inside of a textview (ignoring case), with optional callbacks.

Language: Java

MinSDK: 17

An image of it's functionality and all of the code can be found here.

JavaDocs

To bring into your android project implement the artifact:

In the Project level build.gradle

    allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

In the App level build.gradle

       dependencies {
            implementation 'com.github.Gaineyj0349:Linker:1.2'
    }

How to use:

1 - Construct a Linker object with a textview:

        Linker linker = new Linker(textView);

2 - Add an array or a list of strings to be highlighted within the textview's text:

        ArrayList<String> list = new ArrayList<>();
        list.add("hello");
        list.add("world");
        linker.addStrings(list);

AND/OR

        String[] words = new String[]{"One", "Two", "Three"};
        linker.addStrings(words);

3 - Add a callback: (this is optional):

       linker.setListener(new LinkerListener() {
            @Override
            public void onLinkClick(String charSequenceClicked) {

                // charSequenceClicked is the word that was clicked

                Toast.makeText(MainActivity.this, charSequenceClicked, Toast.LENGTH_SHORT).show();
            }
        });

4 - Call the linker's update method to commit customization and rollout the setup.:

        linker.update();

You always have the option to add Strings to the linker object, just make sure you call the update method after to refresh the spans.

    linker.addStrings("yoda");
    linker.update();

If you need a fresh slate with same linker object just call

       linker.clearLinksList()

You can customize the links also:

1 - Customize all the link colors:

      linker.setAllLinkColors(Color.BLUE);

2 - Customize link underlines:

      linker.setAllLinkUnderline(false);

3 - If you wish to customize a color or underline setting for a certain string (note the string must already be added to the linker):

      linker.setLinkColorForCharSequence("world", Color.MAGENTA);
      linker.setUnderlineModeForCharSequence("world", true);

4 - If you wish to use different setups for every word then you can also give the linker object a list or array of LinkProfiles:

        ArrayList<LinkProfile> profiles = new ArrayList<>();
        profiles.add(new LinkProfile("hello world",
                Color.GREEN, false));
        profiles.add(new LinkProfile("goodbye cruel world",
                Color.RED, false));
        profiles.add(new LinkProfile("Whoa awesome!",
                Color.CYAN, true));


        linker.addProfiles(profiles);

Just remember to call .update() after any additions to the linker object.

Note that the library will take care of subtleties like adding two of the same words, or same parts of a word. For example if "helloworld" and "hello" are two of the words added to the linker, "helloworld" will be given preference over "hello" when they are in the same span of characters. The linker will sort according to larger words first and trace all spans as it links them - avoiding the issue of duplication as well as intersecting spans.

Licensed under MIT license .



来源:https://stackoverflow.com/questions/6843596/android-highlight-a-word-in-a-textview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!