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?




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.


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.


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

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

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.

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

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

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);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.