cómo hacer un texto específico en TextView BOLD

252

No sé cómo hacer que un texto específico en TextView se convierta en NEGRITA.

Es como esto

txtResult.setText(id+" "+name);

Quiero que la salida sea así:

1111 neil

idy nameson variables en las que he recuperado el valor de la base de datos, y quiero ponerlo iden negrita, pero solo idpara nameque no se vea afectado, no tengo idea de cómo hacerlo.

Budi Darmawan
fuente
1
Posible duplicado de ¿Es posible tener múltiples estilos dentro de un TextView?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
4 formas: cadena específica en TextView en negrita : definitivamente lo ayudará.
c49

Respuestas:

379

Simplemente construya su Cadena en HTML y configúrelo:

String sourceString = "<b>" + id + "</b> " + name; 
mytextview.setText(Html.fromHtml(sourceString));
Raghav Sood
fuente
55
Como fromHtml (sourceString) está en desuso en API 24, debe usar el siguiente código: Spanned DurationSpanned; if (android.os.Build.VERSION.SDK_INT> = android.os.Build.VERSION_CODES.N) {DurationSpanned = Html.fromHtml (DurationFormatted, Html.FROM_HTML_MODE_LEGACY); } else {DurationSpanned = Html.fromHtml (DurationFormatted); }
Mladen Rakonjac
2
Esta es la única opción que funcionará si está localizando su aplicación.
howettl
Es una buena solución, pero descubrí que no funciona para la solución <y> @ wtsang02 es más óptima
Omar Boshra
No funciona con <SI usa String.format, A MENOS que también salga del corchete, como se describe aquí .
Yusuf X
55
Html.fromHtml()ahora está en desuso
Someone Somewhere
384

Si bien puede usar Html.fromHtml () , puede usar un enfoque más nativo que es SpannableStringBuilder , esta publicación puede ser útil.

SpannableStringBuilder str = new SpannableStringBuilder("Your awesome text");
str.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), INT_START, INT_END, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
TextView tv=new TextView(context);
tv.setText(str);
wtsang02
fuente
Si esta respuesta no funciona, intente agregar su texto con una cadena que se pueda cambiar, como mSpannable.append (su texto restante);
Gowtham Kumar
10
Para las personas que vienen de Google sin conocimiento previo: INT_START / INT_END son la ubicación en la que las negritas deben comenzar y finalizar.
Spotlight
2
si solo necesita aplicar un marcado a la cadena de origen sin cambiarla, entonces es mejor que use la clase
SpannableString
26
Esto se romperá por completo si necesita localizar su copia. INT_START e INT_END serán diferentes posiciones en diferentes localizaciones.
howettl
44
Trate de comprender qué está haciendo el código cuando tenga dudas. El inicio int es un número que usted define, que es el índice de inicio del intervalo. Pruebe 0 para inicio, cadena. (). Tamaño () para final.
wtsang02
85

Primero: no necesita preocuparse por usar el código de rendimiento lento de la respuesta de Raghav Sood .

Segundo: no necesita escribir una función de extensión proporcionada por la respuesta de w3bshark cuando usa Kotlin.

Finnaly: todo lo que necesita hacer es usar la biblioteca Kotlin android-ktx de Google (consulte aquí para obtener más información y cómo incluirla en su proyecto):

// Suppose id = 1111 and name = neil (just what you want). 
val s = SpannableStringBuilder()
          .bold { append(id) } 
          .append(name)
txtResult.setText(s) 

Produce: 1111 neil


ACTUALIZAR:

Porque creo que puede ayudar a alguien más y demostrar cuán lejos puedes llegar aquí son más casos de uso.

  • Cuando necesite mostrar un texto con algunas partes en azul y cursiva:

    val myCustomizedString = SpannableStringBuilder()
        .color(blueColor, { append("A blue text ") })
        .append("showing that ")
        .italic{ append("it is painless") }
  • Cuando necesite mostrar un texto en negrita y cursiva:

        bold { italic { append("Bold and italic") } }

En resumen, bold, append, colory italicson funciones de extensión a SpannableStringBuilder. Puede ver otras funciones de extensión en la documentación oficial , desde donde puede pensar en otras posibilidades.

Filipe Brito
fuente
Esto es genial y todo, pero creo que cada respuesta relacionada con las cadenas debe considerar las traducciones. Las palabras en las oraciones se pueden ordenar y estructurar de manera completamente diferente en algunos idiomas, por lo que agregarlo de esta manera no siempre es aplicable en ciertas situaciones. Tampoco es ideal para cosas como cadenas de cantidad en XML.
Edward van Raak el
1
@CoolMind No te impide usar Android KTX. Puede encontrar información en github.com/android/android-ktx sobre cómo informar de errores, hacer una sugerencia de características o contribuir a esa biblioteca. Por lo tanto, sigue siendo una referencia válida. He actualizado mi respuesta para incluir más información sobre la biblioteca y cómo usarla en su proyecto.
Filipe Brito
1
¡dale a este chico una medalla por esta solución y recurso modernos! ¡¡¡Gracias!!!
Sjd
37

Pensé que la respuesta elegida no proporcionó un resultado satisfactorio. He escrito mi propia función que toma 2 cadenas; El texto completo y la parte del texto que desea poner en negrita.

Devuelve un SpannableStringBuilder con el 'textToBold' de 'text' en negrita.

Encuentro útil la capacidad de poner en negrita una subcadena sin envolverla en etiquetas.

    /**
     * Makes a substring of a string bold.
     * @param text          Full text
     * @param textToBold    Text you want to make bold
     * @return              String with bold substring
     */

    public static SpannableStringBuilder makeSectionOfTextBold(String text, String textToBold){

        SpannableStringBuilder builder=new SpannableStringBuilder();

        if(textToBold.length() > 0 && !textToBold.trim().equals("")){

            //for counting start/end indexes
            String testText = text.toLowerCase(Locale.US);
            String testTextToBold = textToBold.toLowerCase(Locale.US);
            int startingIndex = testText.indexOf(testTextToBold);
            int endingIndex = startingIndex + testTextToBold.length();
            //for counting start/end indexes

            if(startingIndex < 0 || endingIndex <0){
                return builder.append(text);
            }
            else if(startingIndex >= 0 && endingIndex >=0){

                builder.append(text);
                builder.setSpan(new StyleSpan(Typeface.BOLD), startingIndex, endingIndex, 0);
            }
        }else{
            return builder.append(text);
        }

        return builder;
  }
Eitan
fuente
¿Puedes dar un ejemplo de cómo usar esto en el código?
Micro
2
@MicroR Debe pasar dos cadenas, la segunda cadena debe ser una sección de texto contenida en la primera. por ejemplo, makeSectionOfTextBold ("Este es un texto excelente", "excelente").
Leon
1
debe cambiar su declaración if con if (textToBold! = null &&! textToBold.isEmpty ())
Arda Kara
2
Esta función no espera que la subcadena pueda ocurrir en texto completo varias veces. Por ejemplo, en "Mi nombre de usuario es nombre" no puede poner el segundo "nombre" en negrita.
Jadamec
1
Entonces este método debería llamarse makeAllBold (text, textToBold).
wtsang02
30

Como dijo wtsang02, el uso de HTML es una sobrecarga costosa. Solo usa la solución nativa. Si no tiene que modificar la cadena, simplemente use SpannableString, no SpannableStringBuilder.

String boldText = "id";
String normalText = "name";
SpannableString str = new SpannableString(boldText + normalText);
str.setSpan(new StyleSpan(Typeface.BOLD), 0, boldText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(str);
Jadamec
fuente
23

En caso de que desee utilizar la cadena de XML, puede hacer algo como esto:

strings.xml (la parte "CDATA" es importante, de lo contrario no funcionará)

<string name="test">
     <![CDATA[
 <b>bold!</b> normal
    ]]>
</string>

archivo de diseño

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:layout_gravity="center" />

</FrameLayout>

código

textView.text = HtmlCompat.fromHtml(getString(R.string.test), HtmlCompat.FROM_HTML_MODE_LEGACY)
desarrollador de Android
fuente
Esto funciona para mi <string name="test"><b>text bold</b> other text</string>. No funciona si escribo<![CDATA[
sara
@sara Probado de nuevo ahora, en Pixel 2 con Q. Funciona bien. Aquí, actualicé cómo funciona con Kotlin. Inténtalo de nuevo.
desarrollador de Android
Esta es la respuesta aceptable si usa fuentes personalizadas. Kudus a la crema.
Raghul Sugathan
13

Es simple simplemente cerrar el texto especificado como este, por ejemplo <b>"your text here:"</b>

<string name="headquarters">"<b>"Headquarters:"</b>" Mooresville, North Carolina, U.S.</string>

resultado: Sede central: Mooresville, Carolina del Norte, EE. UU.

Ridha Rezzag
fuente
Esto solo funciona si se usa una cadena de xml. Si esta cadena se llama mediante programación, la codificación html se elimina.
Starwave
11

Si está utilizando Kotlin, se vuelve aún más fácil hacerlo core-ktx, ya que proporciona un lenguaje de dominio específico (DSL) para hacer esto:

val string: SpannedString = buildSpannedString {
    bold {
        append("foo")
    }
    append("bar")     
}

Más opciones proporcionadas por él son:

append("Hello There")
bold {
    append("bold")
    italic {
        append("bold and italic")
        underline {
            append("then some text with underline")
        }
    }
}

Por fin, solo puedes:

textView.text = string
Devansh Maurya
fuente
10

Aquí hay una mejor solución si desea que varios textos estén en negrita. He mejorado el código de Eitan. gracias Eitan

public static SpannableStringBuilder makeSectionOfTextBold(String text, String... textToBold) {
    SpannableStringBuilder builder = new SpannableStringBuilder(text);

    for (String textItem :
            textToBold) {
        if (textItem.length() > 0 && !textItem.trim().equals("")) {
            //for counting start/end indexes
            String testText = text.toLowerCase(Locale.US);
            String testTextToBold = textItem.toLowerCase(Locale.US);
            int startingIndex = testText.indexOf(testTextToBold);
            int endingIndex = startingIndex + testTextToBold.length();

            if (startingIndex >= 0 && endingIndex >= 0) {
                builder.setSpan(new StyleSpan(Typeface.BOLD), startingIndex, endingIndex, 0);
            }
        }
    }

    return builder;
}
Krish
fuente
8

Basado en la respuesta de @ mladj0ni, obtuve el siguiente código para trabajar. El problema era que si usa String.format , elimina el marcado html, por lo que debe escapar de los símbolos de corchetes en strings.xml:

strings.xml:

<string name="welcome_messages">Hello, %1$s! You have &lt;b>%2$d new messages&lt;/b>.</string>

code.java:

String unspanned = String.format(Locale.US, "%s%s", getResources().getString(R.string. welcome_messages), 99);

Spanned spanned;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
    spanned = Html.fromHtml(unspanned, Html.FROM_HTML_MODE_LEGACY);
} else {
    spanned = Html.fromHtml(unspanned);
}

textView.setText(spanned);

Es más simple que SpannableStringBuilder. En cuanto al rendimiento, si está mostrando solo una cadena, el usuario no notará el milisegundo adicional para analizarlo.

Vea la documentación aquí .

Yusuf X
fuente
Gracias por & lt; b> ... & lt; / b>
oxidado
4

Puede usar este código para establecer parte de su texto en negrita. Para lo que sea que esté entre las etiquetas html en negrita, lo hará en negrita.

String myText = "make this <b>bold</b> and <b>this</b> too";
textView.setText(makeSpannable(myText, "<b>(.+?)</b>", "<b>", "</b>"));

public SpannableStringBuilder makeSpannable(String text, String regex, String startTag, String endTag) {

            StringBuffer sb = new StringBuffer();
            SpannableStringBuilder spannable = new SpannableStringBuilder();

            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(text);
            while (matcher.find()) {
                sb.setLength(0);
                String group = matcher.group();
                String spanText = group.substring(startTag.length(), group.length() - endTag.length());
                matcher.appendReplacement(sb, spanText);

                spannable.append(sb.toString());
                int start = spannable.length() - spanText.length();

                spannable.setSpan(new android.text.style.StyleSpan(android.graphics.Typeface.BOLD), start, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            sb.setLength(0);
            matcher.appendTail(sb);
            spannable.append(sb.toString());
            return spannable;
        }
vive el amor
fuente
3
public static Spanned getBoldString(String textNotBoldFirst, String textToBold, String textNotBoldLast) {
    String resultant = null;

    resultant = textNotBoldFirst + " " + "<b>" + textToBold + "</b>" + " " + textNotBoldLast;

    return Html.fromHtml(resultant);

}

Prueba esto. Definitivamente puede ayudar

Saad Bilal
fuente
3

Haga que el primer carácter de cadena sea intercambiable mientras busca caracteres en la lista / reciclador como

r a vi y ajay

anteriormente destacando así, pero quería ser como a continuación

Ravi una Ajay nd O Ravi y un Jay

para esto busqué la longitud de la palabra si es igual a 1, separé la cadena principal en palabras y calculé la posición de inicio de la palabra, luego busqué la palabra que comience con char.

 public static SpannableString colorString(int color, String text, String... wordsToColor) {
    SpannableString coloredString = new SpannableString(text);

    for (String word : wordsToColor) {

        Log.e("tokentoken", "-wrd len-" + word.length());
        if (word.length() !=1) {
            int startColorIndex = text.toLowerCase().indexOf(word.toLowerCase());
            int endColorIndex = startColorIndex + word.length();
            try {
                coloredString.setSpan(new ForegroundColorSpan(color), startColorIndex, endColorIndex,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            } catch (Exception e) {
                e.getMessage();
            }
        } else {
            int start = 0;

            for (String token : text.split("[\u00A0 \n]")) {
                if (token.length() > 0) {
                    start = text.indexOf(token, start);
                   // Log.e("tokentoken", "-token-" + token + "   --start--" + start);
                    char x = token.toLowerCase().charAt(0);
                    char w = word.toLowerCase().charAt(0);
                   // Log.e("tokentoken", "-w-" + w + "   --x--" + x);

                    if (x == w) {
                        // int startColorIndex = text.toLowerCase().indexOf(word.toLowerCase());
                        int endColorIndex = start + word.length();
                        try {
                            coloredString.setSpan(new ForegroundColorSpan(color), start, endColorIndex,
                                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

                        } catch (Exception e) {
                            e.getMessage();
                        }
                    }
                }
            }

        }

    }

    return coloredString;
}
Sagar
fuente
3

Vine aquí para proporcionar una solución más actualizada, porque no estaba satisfecho con las respuestas existentes. Necesitaba algo que funcionara para textos traducidos y no tiene el impacto de usar Html.fromHtml(). Si está utilizando Kotlin, aquí hay una función de extensión que establecerá fácilmente varias partes de su texto en negrita . Esto funciona igual que Markdown, y podría extenderse para admitir otras etiquetas de Markdown, si es necesario.

val yourString = "**This** is your **string**.".makePartialTextsBold()
val anotherString = getString(R.string.something).makePartialTextsBold()

/**
 * This function requires that the parts of the string that need
 * to be bolded are wrapped in ** and ** tags
 */
fun String.makePartialTextsBold(): SpannableStringBuilder {
    var copy = this
    return SpannableStringBuilder().apply {
        var setSpan = true
        var next: String
        do {
            setSpan = !setSpan
            next = if (length == 0) copy.substringBefore("**", "") else copy.substringBefore("**")
            val start = length
            append(next)
            if (setSpan) {
                setSpan(StyleSpan(Typeface.BOLD), start, length,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            }
            copy = copy.removePrefix(next).removePrefix("**")
        } while (copy.isNotEmpty())
    }
}
w3bshark
fuente
3

wtsang02 respuesta de es la mejor manera de hacerlo, ya que Html.fromHtml ("") ahora está en desuso. Aquí voy a mejorarlo un poco para quien tenga problemas para hacer que la primera palabra en negrita sea dinámica, sin importar el tamaño de la oración.

Primero, creemos un método para obtener la primera palabra:

 private String getFirstWord(String input){

    for(int i = 0; i < input.length(); i++){

        if(input.charAt(i) == ' '){

            return input.substring(0, i);
        }
    }

    return input;
}

Ahora supongamos que tiene una cadena larga como esta:

String sentence = "[email protected] want's to be your friend!"

¡Y quieres que tu oración sea como [email protected] quiere que sea tu amigo! Todo lo que tienes que hacer es obtener la primera palabra y obtener la longitud para hacer que la primera palabra sea en negrita, algo como esto:

String myFirstWord = getFirstWord(sentence);
int start = 0; // bold will start at index 0
int end = myFirstWord.length(); // and will finish at whatever the length of your first word

Ahora solo sigue los pasos de wtsang02 , así:

SpannableStringBuilder fancySentence = new SpannableStringBuilder(sentence);
fancySentence.setSpan(new android.text.style.StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(fancySentence);

¡Y eso es! Ahora deberías poder poner en negrita una palabra con cualquier tamaño de oración larga / corta. Espero que ayude a alguien, feliz codificación :)

Junia Montana
fuente
3

Esta es la función de extensión de Kotlin que uso para esto

/**
 * Sets the specified Typeface Style on the first instance of the specified substring(s)
 * @param one or more [Pair] of [String] and [Typeface] style (e.g. BOLD, ITALIC, etc.)
 */
fun TextView.setSubstringTypeface(vararg textsToStyle: Pair<String, Int>) {
    val spannableString = SpannableString(this.text)
    for (textToStyle in textsToStyle) {
        val startIndex = this.text.toString().indexOf(textToStyle.first)
        val endIndex = startIndex + textToStyle.first.length

        if (startIndex >= 0) {
            spannableString.setSpan(
                StyleSpan(textToStyle.second),
                startIndex,
                endIndex,
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
            )
        }
    }
    this.setText(spannableString, TextView.BufferType.SPANNABLE)
}

Uso:

text_view.text="something bold"
text_view.setSubstringTypeface(
    Pair(
        "something bold",
        Typeface.BOLD
    )
)

.

text_view.text="something bold something italic"
text_view.setSubstringTypeface(
    Pair(
        "something bold ",
        Typeface.BOLD
    ),
    Pair(
        "something italic",
        Typeface.ITALIC
    )
)
aaronmarino
fuente
2

Puede agregar las dos cadenas por separado en el generador, una de ellas es spanSString, la otra es una normal. De esta manera no tiene que calcular los índices.

val instructionPress = resources?.getString(R.string.settings_press)

val okText = resources?.getString(R.string.ok)
val spannableString = SpannableString(okText)

val spannableBuilder = SpannableStringBuilder()
spannableBuilder.append(instructionPress)
spannableBuilder.append(spannableString, StyleSpan(Typeface.BOLD), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

instructionText.setText(spannableBuilder,TextView.BufferType.SPANNABLE)
Евелина Дервентска
fuente
2

si la posición del texto en negrita es fija (por ejemplo: si está al comienzo de textView), use dos textView diferentes con el mismo fondo. Luego puede hacer que el otro textStyle de textView sea negrita.

Esto requerirá el doble de memoria en comparación con un solo TextView, pero la velocidad aumentará.

neens
fuente
1

He creado un método estático para configurar parte del texto en negrita para TextView y EditText

public static void boldPartOfText(View mView, String contentData, int startIndex, int endIndex){
        if(!contentData.isEmpty() && contentData.length() > endIndex) {
            final SpannableStringBuilder sb = new SpannableStringBuilder(contentData);

            final StyleSpan bss = new StyleSpan(Typeface.BOLD); // Span to make text bold
            final StyleSpan iss = new StyleSpan(Typeface.NORMAL); //Span to make text normal
            sb.setSpan(iss, 0, startIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
            sb.setSpan(bss, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
            sb.setSpan(iss,endIndex, contentData.length()-1, Spanned.SPAN_INCLUSIVE_INCLUSIVE);

            if(mView instanceof TextView)
               ((TextView) mView).setText(sb);
            else if(mView instanceof EditText)
               ((EditText) mView).setText(sb);

        }
    }

Otro código mas personalizado

  /*typeFaceStyle can be passed as 

    Typeface.NORMAL = 0;
    Typeface.BOLD = 1;
    Typeface.ITALIC = 2;
    Typeface.BOLD_ITALIC = 3;*/

    public static void boldPartOfText(View mView, String contentData, int startIndex, int endIndex,int typeFaceStyle){
        if(!contentData.isEmpty() && contentData.length() > endIndex) {
            final SpannableStringBuilder sb = new SpannableStringBuilder(contentData);

            final StyleSpan bss = new StyleSpan(typeFaceStyle); // Span to make text bold
            final StyleSpan iss = new StyleSpan(Typeface.NORMAL); //Span to make text italic
            sb.setSpan(iss, 0, startIndex, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
            sb.setSpan(bss, startIndex, endIndex, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
            sb.setSpan(iss,endIndex,contentData.length()-1,Spanned.SPAN_INCLUSIVE_INCLUSIVE);

            if(mView instanceof TextView)
                ((TextView) mView).setText(sb);
            else if(mView instanceof EditText)
                ((EditText) mView).setText(sb);
        }
    }
Zar E Ahmer
fuente
1

En caso de que alguien esté usando el enlace de datos. Podemos definir un adaptador de enlace como este

@BindingAdapter("html")
fun setHtml(view: TextView, html: String) {
    view.setText(HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY))
}

Entonces podemos usarlo en un TextView

app:html="@{@string/bold_text}"

donde bold_text es

<string name="bold_text"><![CDATA[Part of text is <b>bold</b>]]></string>
logcat
fuente
¿Dónde escribes la función "setHtml"?
Desarrollador de Android
developer.android.com/topic/libraries/data-binding/… Es básicamente cualquier clase, siempre que tenga una anotación
logcat
Oh, esto es muy raro para mi. Gracias. ¿Conoces quizás un buen tutorial / muestra para los recién llegados de este tema?
Desarrollador de Android
No sé de tutoriales. Solo google "android BindingAdapter"
logcat
1

Encontró una manera en caso de que desee manejar la localización en varios idiomas, es aburrido pero funciona, supongamos que queremos esto:

En inglés:

No hay pagos registrados

En español:

No hay pagos registrados

Tienes que crear 3 cuerdas

Inglés:

<string name="start_string">There are no</string>
<string name="middle_string">payments</string>
<string name="end_string">registered.</string>
<string name="string_format" translatable="false">%1$s %2$s %3$s</string>

Español:

<string name="start_string">No hay</string>
<string name="middle_string">pagos</string>
<string name="end_string">registrados</string>

Ahora puedes hacer esto:

val startSpanPosition = getString(R.string.start_string).length
val endSpanPosition = startSpanPosition + getString(R.string.middle_string).length
val mySpannableString = SpannableStringBuilder(String.format(getString(R.string.string_format),
        getString(R.string.start_string), getString(R.string.middle_string))), getString(R.string.end_string)))

mySpannableString.setSpan(StyleSpan(Typeface.BOLD), spanStartPosition, endSpanPosition, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
Jesus Almaral - Hackaprende
fuente
1

Su recurso de cadena

<resources>
   <string name="your_string_resource_name">This is normal text<![CDATA[<b> but this is bold </b>]]> and <![CDATA[<u> but this is underline text</u>]]></string>
</resources> 

tu clase de java

yourtextView.setText(getString(R.string.your_string_resource_name));
Yldirim
fuente
0

Aquí está mi solución completa para valores dinámicos de cadenas con verificación de casos.

/**
 * Makes a portion of String formatted in BOLD.
 *
 * @param completeString       String from which a portion needs to be extracted and formatted.<br> eg. I am BOLD.
 * @param targetStringToFormat Target String value to format. <br>eg. BOLD
 * @param matchCase Match by target character case or not. If true, BOLD != bold
 * @return A string with a portion formatted in BOLD. <br> I am <b>BOLD</b>.
 */
public static SpannableStringBuilder formatAStringPortionInBold(String completeString, String targetStringToFormat, boolean matchCase) {
    //Null complete string return empty
    if (TextUtils.isEmpty(completeString)) {
        return new SpannableStringBuilder("");
    }

    SpannableStringBuilder str = new SpannableStringBuilder(completeString);
    int start_index = 0;

    //if matchCase is true, match exact string
    if (matchCase) {
        if (TextUtils.isEmpty(targetStringToFormat) || !completeString.contains(targetStringToFormat)) {
            return str;
        }

        start_index = str.toString().indexOf(targetStringToFormat);
    } else {
        //else find in lower cases
        if (TextUtils.isEmpty(targetStringToFormat) || !completeString.toLowerCase().contains(targetStringToFormat.toLowerCase())) {
            return str;
        }

        start_index = str.toString().toLowerCase().indexOf(targetStringToFormat.toLowerCase());
    }

    int end_index = start_index + targetStringToFormat.length();
    str.setSpan(new StyleSpan(BOLD), start_index, end_index, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return str;
}

P.ej. completeString = "Estoy en negrita"

CASO I si *targetStringToFormat* = "bold"y*matchCase* = true

devuelve "I BOLD" (ya que negrita! = BOLD)

CASO II si *targetStringToFormat* = "bold"y*matchCase* = false

devuelve "I BOLD "

Aplicar:

myTextView.setText(formatAStringPortionInBold("I am BOLD", "bold", false))

¡Espero que ayude!

sud007
fuente