Zmień kolor tekstu jednego słowa w TextView


97

Szukam sposobu, aby zmienić kolor tekstu pojedynczego słowa w a TextViewod wewnątrz Activity.

Na przykład z tym:

String first = "This word is ";
String next = "red"
TextView t = (TextView) findViewById(R.id.textbox);
t.setText(first + next);

Jak zmienić kolor nexttekstu na czerwony?




Odpowiedzi:


173

Najłatwiejszy sposób, jaki znam, to po prostu użycie html.

String first = "This word is ";
String next = "<font color='#EE0000'>red</font>";
t.setText(Html.fromHtml(first + next));

Ale będzie to wymagało przebudowania TextView, gdy (jeśli?) Chcesz zmienić kolor, co może spowodować kłopoty.


1
Jest to zdecydowanie najprostszy sposób, ale kolor nie powinien być color = '# EE0000' - do oznaczenia koloru szesnastkowego potrzebny jest symbol funta.
Tom

Naprawiono, dzięki! Nie przypominam sobie, czy skopiowałem to z rzeczywistego kodu lub z pamięci ze stroną generującą kolory, więc mogło to wcześniej nie działać.
Dan

Ok, tylko się upewniam! Ponadto, jak się dowiedziałem, nie można używać 8-cyfrowych kodów szesnastkowych, więc nie ma komponentu alfa. Ten na moment mnie zaskoczył.
Tom

Używanie fromHtmljest teraz przestarzałe
Alex Jolig

Html.fromHtmljest przestarzałe. To rozwiązanie zadziałało dla mnie!
coderpc

74
t.setText(first + next, BufferType.SPANNABLE);
Spannable s = (Spannable)t.getText();
int start = first.length();
int end = start + next.length();
s.setSpan(new ForegroundColorSpan(0xFFFF0000), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

musisz użyć spannable, co pozwoli ci również zwiększyć rozmiar tekstu, pogrubić go itp. ... nawet wstawić obraz.


4
Dobra odpowiedź, dzięki. W tym przypadku zamiast „start + next.length ()” można użyć „s.length ()”: int end = s.length ();
Oleg

1
Na wypadek, gdyby ktoś szukał rozwiązania Xamarin.Android. Możesz przypisać SpannableStringobiekt za pomocą TextFormattedwłaściwości kontrolki.
Jamshaid Kamran

Nie udało się uruchomić tego. Skończyło się na rozwiązaniu BK.
2b77bee6-5445-4c77-b1eb-4df3e5

1. Jeśli istnieje kompilacja, zawsze lepiej jej użyć. 2. co Ci nie wyszło? to rozwiązanie jest stare, bardzo stare, niektóre pliki API zostały zmienione, dodane, usunięte, naprawiono błąd, co dokładnie nie działa?
codeScriber

2
Otrzymuję java.lang.String cannot be cast to android.text.Spannablebłąd.
lashgar

37

Użyj SpannableStringBuilder w ten sposób:

SpannableStringBuilder builder = new SpannableStringBuilder();

SpannableString str1= new SpannableString("Text1");
str1.setSpan(new ForegroundColorSpan(Color.RED), 0, str1.length(), 0);
builder.append(str1);

SpannableString str2= new SpannableString(appMode.toString());
str2.setSpan(new ForegroundColorSpan(Color.GREEN), 0, str2.length(), 0);
builder.append(str2);

TextView tv = (TextView) view.findViewById(android.R.id.text1);
tv.setText( builder, TextView.BufferType.SPANNABLE);

Czy jest coś, czym mogę zastąpić, new ForegroundColorSpan(Color)aby tekst zachował oryginalny, domyślny kolor?
cjnash

Jak dodać zwykły tekst (ciąg) w środku widoku tekstu?
Ragavendra M

5

dla długich ciągów możesz użyć tego:

String help = getString(R.string.help);
help = help.replace("some word", "<font color='#EE0000'>some word</font>");
txtDesc.setText(Html.fromHtml(help));

2

Jeśli chcesz zmienić stan wszystkich wystąpień określonego Stringw TextViewtekście (bez rozróżniania wielkości liter), możesz użyć StringBuilders i SpannableStringtak:

StringBuilder textBuilder = new StringBuilder(myTextView.getText().toString());
StringBuilder searchedTextBuilder = new StringBuilder((mySearchedString));
SpannableString spannableString = new SpannableString(myTextView.getText().toString());

int counter = 0;
int index = 0;

for (int i = 0;i < textBuilder.length() - mySearchedString.length() - 1;i++)
{
    counter = 0;
    if (Character.toLowerCase(textBuilder.charAt(i)) == Character.toLowerCase(searchedTextBuilder.charAt(index)))
    {
        counter++;
        index++;
        for (int j = 1,z = i + 1;j < mySearchedString.length() - 1;j++,z++)
        {
            if (Character.toLowerCase(textBuilder .charAt(z)) == Character.toLowerCase(searchedTextBuilder .charAt(index)))
            {
                counter++;
                index++;
            }
            else
            {
                index++;
                if (index % mySearchedString.length() == 0)
                {
                    index = 0;
                }
                break;
             }
        }
        if (counter == mySearchedString.length() - 1) // A match
        {
            spannableString.setSpan(new ForegroundColorSpan(Color.RED), i,
                                i + mySearchedString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // Do the change you want(In this case changing the fore ground color to red)
            index = 0;
            continue;
        }
        else
        {
            index = 0;
            continue;
        }
    }
}
myTextView.setText(spannableString);

}

  • Przechowuj cały TextViewtekst w pliku StringBuilder.
  • Przechowuj wyszukiwany ciąg w pliku StringBuilder.
  • Przechowuj cały TextViewtekst w plikuSpannableString
  • Wykonaj prostą operację, aby znaleźć wszystkie Stringwystąpienia w TextViewtekście i zmienić je po osiągnięciu.
  • Ustaw wartość tekstową TextViewna SpannableString.

1

Zaimplementowałem funkcję narzędziową w Kotlinie na własny użytek i może być przydatna dla kogoś innego.

fun getCusomTextWithSpecificTextWithDiffColor(textToBold: String, fullText: String,
                                                  targetColor: Int) =
            SpannableStringBuilder(fullText).apply {
                setSpan(ForegroundColorSpan(targetColor),
                        fullText.indexOf(textToBold),
                        (fullText.indexOf(textToBold) + textToBold.length),
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            }

Jak go używam:

context?.let {
        infoMessage.text = AppUtils.getCusomTextWithSpecificTextWithDiffColor(
                wordAsBold,
                completeSentence, ContextCompat.getColor(it, R.color.white))
    }

1

POSŁUGIWAĆ SIĘ:

makeTextBold("Your order is accepted","accepted", textView);
makeTextBold("Your order is canceled","canceled", textView);

Funkcjonować:

public static void makeTextBold(String sentence, String word, AppCompatTextView textView) {
    SpannableStringBuilder builder = new SpannableStringBuilder();
    int startIndex = sentence.indexOf(word.toLowerCase().trim());
    int endIndex = startIndex + word.toLowerCase().trim().length();
    SpannableString spannableString = new SpannableString(sentence);
    StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
    spannableString.setSpan(boldSpan, startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //To make text Bold
    spannableString.setSpan(new ForegroundColorSpan(Color.RED), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); //To change color of text
    builder.append(spannableString);
    textView.setText(builder, TextView.BufferType.SPANNABLE);
}

0

Myślę, że jest to bardziej czytelne w przypadku kolorowania słowa w ciągu, ale jest też prawdopodobnie bardziej wydajne, ponieważ piszesz raz

    String str  = YOUR_STRING
    Spannable s = new SpannableString(str);
    int start = str.indexOf(err_word_origin);
    int end =  start + err_word_origin.length();
    s.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    YOUR_TEXT_VIEW.setText(s , TextView.BufferType.SPANNABLE);
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.