5

I have a string that has specific words I want to color. Those words are the one's that start with #.

    if(title.contains("#")){

        SpannableString WordtoSpan = new SpannableString(title);   

        int idx = title.indexOf("#");
        if (idx >= 0) {

            Pattern pattern = Pattern.compile("[ ,\\.\\n]");
            Matcher matcher = pattern.matcher(title);
            int wordEnd = matcher.find(idx)? matcher.start() : -1;

            if (wordEnd < 0) {
                wordEnd = title.length();
            }
            WordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE),
                        idx,
                        wordEnd,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }           

        holder.txtTitle.setText(WordtoSpan);
    } else {
        holder.txtTitle.setText(title);
    }

Now lets take for example this string Bold part is for example the colored words.

I love cheese #burgers, and with #ketchup.

^ This is my current thing with my code. What I want is to color every # word, not just first one.

ex. It'll be like

I love cheese #burgers, and with #ketchup.

I think I need to loop? But couldn't get it clearly and working x.x


Update: Latest try. List becomes blank.

    SpannableString WordtoSpan = new SpannableString(title);

    int end = 0;

    Pattern pattern = Pattern.compile("[ ,\\.\\n]");
    Matcher matcher = pattern.matcher(title);

    int i = title.indexOf("#");

    for (i = 0; i < title.length(); i++) {
    if (i >= 0) {

        int wordEnd = matcher.find(i)? matcher.start() : -1;

        if (wordEnd < 0) {
            wordEnd = title.length();
        }
        WordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE),
                    i,
                    wordEnd,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

        i = end;
    }    

    holder.txtTitle.setText(WordtoSpan);
    }

5 Answers 5

8
+50

I had provided this answer earlier here - https://stackoverflow.com/a/20179879/3025732

String text = "I love chicken #burger , cuz they are #delicious";
//get the text from TextView

Pattern HASHTAG_PATTERN = Pattern.compile("#(\\w+|\\W+)");
Matcher mat = HASHTAG_PATTERN.matcher(text);

while (mat.find()) {
  String tag = mat.group(0);

  //String tag will contain the hashtag
  //do operations with the hashtag (change color)
}

[EDIT]

I've modified the code and done it according to what you need:

SpannableString hashText = new SpannableString(text.getText().toString());
Matcher matcher = Pattern.compile("#([A-Za-z0-9_-]+)").matcher(hashText);
while (matcher.find())
{
     hashText.setSpan(new ForegroundColorSpan(Color.BLUE), matcher.start(), matcher.end(), 0);
}
text.setText(hashText);

Here's a screenshot of it:

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

But I dont know how to "do the operation", I'm a beginner, trying to develop with my bro. So how to supply end, start etc..
@JohnJared Please check my updated answer with the code sample you wanted
4

I'm surprised that no one has mentioned this:

// String you want to perform on
String toChange = "I love cheese #burgers, and with #ketchup.";

// Matches all characters, numbers, underscores and dashes followed by '#'
// Does not match '#' followed by space or any other non word characters
toChange = toChange.replaceAll("(#[A-Za-z0-9_-]+)", 
                         "<font color='#0000ff'>" + "$0" +  "</font>");

// Encloses the matched characters with html font tags

// Html#fromHtml(String) returns a Spanned object
holder.txtTitle.setText(Html.fromHtml(toChange));

#0000ff ==>> Color.BLUE

Screenshot:

enter image description here

13 Comments

@JohnJared Added a screenshot above. Could the problem be somewhere else in your code?
Umm, found out why. Cuz in my app I have arabic letter with # thats i why, but when I changed arabic to eng they worked. How can I make it color arabic words too?
أ ب ت ث ج ح خ د ذ ل ز ر ع غ ف ق س ش ص ض ط ظ م ر ه ن و ي
I should wait 16 hrs, after 16 hrz ill give u the +50, thanks!
Nope, but I gave that person +50 by mistake x.x sorry. I'll start another bounty on the next question I ask and I will reward you it. I am very sorry
|
1

You need to loop through your matches. There is a previous post you can have a look at here:

Finding Multiple Integers Inside A String Using Regex

2 Comments

It's fine to find them(I can use .split("#"), but how to find them and color them inside the string at the same time?
if(title.contains("#")){ Matcher matcher = pattern.matcher(title); while ( matcher.find() ) { //do ForegroundcolorSpan etc } }
1

Check following example :

String title = "Your #complete sentence #testing #test.";
printUsingNormal(title);
printUsingRegex(title);

private static void printUsingRegex(String title) {
    Pattern pattern = Pattern.compile("[ ,\\.\\n]");

    int start = 0;
    int end = 0;
    Matcher matcher = pattern.matcher(title);
    while (end >= 0 && end < title.length()) {
        start = title.indexOf('#', start);
        if (start > 0) {
            end = matcher.find(start) ? matcher.start() : -1;
            if (end > 0) {
                System.out.println("Word : " + title.substring(start, end)
                        + " Start : " + start + " End : " + end);
                start = end;
            }
        } else {
            break;
        }
    }
}

private static void printUsingNormal(String title) {
    int start = 0;
    for (int i = 0; i < title.length(); i++) {
        char c = title.charAt(i);
        if (c == '#') {
            start = i; // Got the starting hash
            int end = title.indexOf(' ', i + 1); // Finding the next space.
            if (end > 0) {
                System.out.println("Word : " + title.substring(start, end)
                        + " Start : " + start + " End : " + end);
                i = end;
            } else {
                end=title.length()-1;
                System.out.println("Word : " + title.substring(start, end)
                        + " Start : " + start + " End : " + end);
                i = end;
            }
        }
    }
}

3 Comments

Please find my updated answer above. which uses both regex and direct way.
Umm, now I'm confused. How do I use it now? Can you do the regex way with the old answer ?(so regex+the loop int i)
please check my latest try in my answer's update. See what I mean, and what Am I missing.
0

Use while(), this is the snippet for setting the background color of text searched in android native messenger, you can try the same in your code.

1 Comment

check my updated question, I tried using while. Now nothing appears on the list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.