Alterar a cor do texto de uma palavra em um TextView

97

Estou procurando uma maneira de mudar a cor de um texto de uma única palavra TextViewde dentro de um Activity.

Por exemplo, com este:

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

Como eu mudaria a cor do nexttexto para vermelho?

derramador de cereais
fonte
stackoverflow.com/questions/9754076/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respostas:

172

A maneira mais fácil que conheço é apenas usar html.

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

Mas isso exigirá que você reconstrua o TextView quando (se?) Quiser alterar a cor, o que pode causar problemas.

Dan
fonte
1
Esta é definitivamente a maneira mais simples, mas a cor não deveria ser color = '# EE0000' o símbolo da libra é necessário para denotar uma cor hexadecimal.
Tom
Corrigido, obrigado! Não me lembro se copiei do código real ou da memória com um site de gerador de cores, então pode não ter funcionado antes.
Dan
Ok, apenas tendo certeza! Além disso, como descobri que você não pode usar códigos hexadecimais de 8 dígitos, nenhum componente alfa. Aquilo me deixou perplexo por um momento.
Tom
O uso fromHtmlestá obsoleto agora
Alex Jolig
Html.fromHtmlestá obsoleto. Essa solução funcionou para mim!
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);

você tem que usar o spannable isso também permite que você aumente o tamanho do texto, torne-o em negrito etc .... até mesmo coloque alguma imagem.

codeScriber
fonte
4
Boa resposta, obrigado. Neste caso, "s.length ()" pode ser usado em vez de "start + next.length ()": int end = s.length ();
Oleg
1
Caso alguém esteja procurando a Solução Xamarin.Android. Você pode atribuir o SpannableStringobjeto usando a TextFormattedpropriedade do seu controle.
Jamshaid Kamran
Não foi possível fazer isso funcionar. Acabei indo com a solução do BK.
2b77bee6-5445-4c77-b1eb-4df3e5
1. se houver uma construção, é sempre melhor usá-la. 2. o que não funcionou para você? esta solução é antiga, muito antiga, algumas apis foram alteradas, adicionadas, removidas, bug corrigido, o que exatamente não funcionou?
codeScriber
2
Recebo java.lang.String cannot be cast to android.text.Spannableerro.
lashgar
37

Use SpannableStringBuilder assim:

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
fonte
Há algo que eu possa substituir new ForegroundColorSpan(Color)para que o texto mantenha a cor padrão original?
cjnash
Como adicionar texto simples (String) no meio do textview?
Ragavendra M
5

para string longa, você pode usar isto:

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

Se você quiser alterar o estado de todas as instâncias de um específico Stringdentro de um TextViewtexto (maiúsculas e minúsculas) que você pode usar StringBuilders e SpannableStringcomo isto:

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

}

  • Armazene todo o TextViewtexto dentro de umStringBuilder .
  • Armazene a string pesquisada dentro de um StringBuilder.
  • Armazene todo o TextViewtexto dentro de umSpannableString
  • Faça uma operação simples para encontrar todas as Stringinstâncias dentro do TextViewtexto e alterá-las quando alcançadas.
  • Defina o valor do texto de TextViewpara SpannableString.
Deus
fonte
1

Implementei uma função de utilidade no Kotlin para meu próprio caso de uso e talvez útil para outra pessoa.

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

Como estou usando:

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

USAR:

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

Função:

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
fonte
0

Eu acho que isso é mais legível para colorir uma palavra em uma string e também provavelmente um pouco mais eficiente porque você escreve uma vez

    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
fonte