Cambiar el color del texto de una palabra en TextView

97

Estoy buscando una forma de cambiar el color de un texto de una sola palabra en un TextViewdesde dentro de un Activity.

Por ejemplo, con esto:

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

¿Cómo cambiaría el color del nexttexto a rojo?

vertedor de cereales
fuente
stackoverflow.com/questions/9754076/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respuestas:

172

La forma más fácil que conozco es simplemente usar html.

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

Pero esto requerirá que reconstruya el TextView cuando (¿si?) Desee cambiar el color, lo que podría causar problemas.

Dan
fuente
1
Esta es definitivamente la forma más sencilla, pero si el color no debería ser color = '# EE0000', se necesita el símbolo de libra para indicar un color hexadecimal.
Tom
¡Arreglado, gracias! No recuerdo si copié esto del código real o de la memoria con un sitio web generador de color, por lo que es posible que no haya funcionado antes.
Dan
¡OK. Solamente me estaba asegurando! Además, como descubrí, no puede usar códigos hexadecimales de 8 dígitos, por lo que no hay componente alfa. Ese me dejó perplejo por un momento.
Tom
El uso fromHtmlestá obsoleto ahora
Alex Jolig
Html.fromHtmles obsoleto. ¡Esta solución funcionó para mí!
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);

tienes que usar spannable, esto también te permitirá aumentar el tamaño del texto, ponerlo en negrita, etc. incluso poner una imagen.

codeScriber
fuente
4
Buena respuesta, gracias. En este caso, se puede utilizar "s.length ()" en lugar de "start + next.length ()": int end = s.length ();
Oleg
1
En caso de que alguien busque Xamarin.Android Solution. Puede asignar un SpannableStringobjeto utilizando la TextFormattedpropiedad de su control.
Jamshaid Kamran
No se pudo hacer que esto funcione. Terminé yendo con la solución de BK.
2b77bee6-5445-4c77-b1eb-4df3e5
1. si hay una compilación, siempre es mejor usarla. 2. ¿Qué no funcionó para ti? esta solución es vieja, muy vieja, algunas apis han cambiado, agregado, eliminado, error corregido, ¿qué es exactamente lo que no funcionó?
codeScriber
2
Me sale un java.lang.String cannot be cast to android.text.Spannableerror.
Lashgar
37

Utilice SpannableStringBuilder así:

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
fuente
¿Hay algo que pueda reemplazar new ForegroundColorSpan(Color)para que el texto conserve su color predeterminado original?
cjnash
¿Cómo agregar texto sin formato (cadena) en medio de la vista de texto?
Ragavendra M
5

para una cadena larga, puede usar esto:

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

Si desea cambiar el estado de todas las instancias de un específico Stringdentro de un TextViewtexto (no distingue entre mayúsculas y minúsculas), puede usar StringBuilders y SpannableStringasí:

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

}

  • Guarde todo el TextViewtexto dentro de un StringBuilder.
  • Guarde la cadena buscada dentro de un StringBuilder.
  • Guarde el TextViewtexto completo dentro de unSpannableString
  • Realice una operación simple para encontrar todas las Stringinstancias dentro del TextViewtexto y cámbielas cuando llegue.
  • Establezca el valor de texto de TextViewen SpannableString.
Dios
fuente
1

Implementé una función de utilidad en Kotlin para mi propio caso de uso y tal vez sea útil para otra persona.

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

Cómo lo estoy usando:

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

UTILIZAR:

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

Función:

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

Creo que esto es más legible para colorear una palabra en una cadena, probablemente también sea un poco más eficiente porque escribes una 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
fuente