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?

zbożowy
źródło
stackoverflow.com/questions/9754076/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

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.

Dan
źródło
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.

codeScriber
źródło
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);
Biswajit Karmakar
źródło
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));
Maysam R
źródło
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.
Bóg
źródło
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))
    }
Wahib Ul Haq
źródło
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);
}
Ketan Ramani
źródło
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);
sivi
źródło