Palabras en negrita en una cadena de strings.xml en Android

114

Tengo un texto largo en una de las cadenas en strings.xml. Quiero poner en negrita y cambiar el color de algunas palabras en ese texto.

¿Cómo puedo hacerlo?

carolino
fuente
¿Puede ser un poco más específico en términos de lo que está tratando de lograr en general?
Brian

Respuestas:

192

Básicamente, podría usar etiquetas html en su recurso de cadena como:

<resource>
    <string name="styled_welcome_message">We are <b><i>so</i></b> glad to see you.</string>
</resources>

Y use Html.fromHtml o use spannable, verifique el enlace que publiqué.

Antigua pregunta similar: ¿es posible tener varios estilos dentro de un TextView?

David Olsson
fuente
16
Además, dependiendo de cómo use su cadena de recursos, es posible que deba colocar las etiquetas en negrita / cursiva en un bloque CDATA para que no se analicen hasta que las use Html.fromHtml(): ... <![CDATA[<b><i>so</i></b>]]>...
dule
133
Para cualquier otra persona que haya encontrado la documentación oficial de Android un poco vaga en esto: si usa etiquetas como <b> en su recurso de cadena, asegúrese de recuperarlo usando en getText(R.string.whatever)lugar degetString(R.string.whatever)
andygeers
1
¿No se supone que sea en namelugar de id?
Hendra Anggrian
4
Entonces no hay necesidad de Html.fromHtmlo Spannable. Solo usa getText(R.string.whatever)como @andygeers mencionado.
Alaa M.
1
@andygeers ¿Qué podemos hacer con una cadena como "Mi nombre es <b>% s </b>" que no puede usar getText ya que solo acepta un único parámetro?
Taylor
45

Use la etiqueta html dentro de los recursos de cadena: -

<resources>
<string name="string_resource_name"><![CDATA[<b> Your text </b>]]> </string>
</resources>

Y obtenga texto en negrita de recursos de cadena como: -

private Spanned getSpannedText(String text) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return Html.fromHtml(text, Html.FROM_HTML_MODE_COMPACT);
        } else {
            return Html.fromHtml(text);
        }
    }


 String s = format(context.getResources().getString(R.string.string_resource_name));
 textView.setText(getSpannedText(s));
Sagar Chorage
fuente
es la mejor respuesta y funciona totalmente para las personas que usan @BindingAdapter. Gracias hermano.
Sup.Ia
44

Como ha dicho David Olsson, puede usar HTML en sus recursos de cadena:

<resource>
    <string name="my_string">A string with <i>actual</i> <b>formatting</b>!</string>
</resources>

Luego, si usa en getText(R.string.my_string)lugar de getString(R.string.my_string), obtiene un en CharSequencelugar de un Stringque contiene el formato incrustado.

andygeers
fuente
getText devuelve CharSequence no un Spannable
Tigran Babajanyan
1
¿Qué pasa si su cadena es una cantidad a la que necesita agregar un número?
Taylor
getText no le permite usar marcadores de posición
Vincent_Paing
10

En kotlin, puede crear funciones de extensiones en recursos (actividades | fragmentos | contexto) que convertirán su cadena en un intervalo html

p.ej

fun Resources.getHtmlSpannedString(@StringRes id: Int): Spanned = getString(id).toHtmlSpan()

fun Resources.getHtmlSpannedString(@StringRes id: Int, vararg formatArgs: Any): Spanned = getString(id, *formatArgs).toHtmlSpan()

fun Resources.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int): Spanned = getQuantityString(id, quantity).toHtmlSpan()

fun Resources.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): Spanned = getQuantityString(id, quantity, *formatArgs).toHtmlSpan()

fun String.toHtmlSpan(): Spanned = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)
} else {
    Html.fromHtml(this)
}

Uso

//your strings.xml
<string name="greeting"><![CDATA[<b>Hello %s!</b><br>]]>This is newline</string>

//in your fragment or activity
resources.getHtmlSpannedString(R.string.greeting, "World")

EDITA aún más extensiones

fun Context.getHtmlSpannedString(@StringRes id: Int): Spanned = getString(id).toHtmlSpan()

fun Context.getHtmlSpannedString(@StringRes id: Int, vararg formatArgs: Any): Spanned = getString(id, *formatArgs).toHtmlSpan()

fun Context.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int): Spanned = resources.getQuantityString(id, quantity).toHtmlSpan()

fun Context.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): Spanned = resources.getQuantityString(id, quantity, *formatArgs).toHtmlSpan()


fun Activity.getHtmlSpannedString(@StringRes id: Int): Spanned = getString(id).toHtmlSpan()

fun Activity.getHtmlSpannedString(@StringRes id: Int, vararg formatArgs: Any): Spanned = getString(id, *formatArgs).toHtmlSpan()

fun Activity.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int): Spanned = resources.getQuantityString(id, quantity).toHtmlSpan()

fun Activity.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): Spanned = resources.getQuantityString(id, quantity, *formatArgs).toHtmlSpan()


fun Fragment.getHtmlSpannedString(@StringRes id: Int): Spanned = getString(id).toHtmlSpan()

fun Fragment.getHtmlSpannedString(@StringRes id: Int, vararg formatArgs: Any): Spanned = getString(id, *formatArgs).toHtmlSpan()

fun Fragment.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int): Spanned = resources.getQuantityString(id, quantity).toHtmlSpan()

fun Fragment.getQuantityHtmlSpannedString(@PluralsRes id: Int, quantity: Int, vararg formatArgs: Any): Spanned = resources.getQuantityString(id, quantity, *formatArgs).toHtmlSpan()
svkaka
fuente
@Himanshu Mori algún fragmento ayudaría. ¿Lo estás usando en la clase de kotlin?
svkaka
1
Las extensiones de actividad no son necesarias, la actividad es el contexto en sí mismo
Farshad Tahmasbi
2

Strings.xml

<string name="my_text"><Data><![CDATA[<b>Well Done !</b><br></br>All of your activities are completed.<br></br>You may now close the app.<br></br>See you again next time.]]></Data></string>

Para configurar

textView.setText(Html.fromHtml(getString(R.string.activity_completed_text)));
kunal khedkar
fuente
1

Puedes hacerlo desde cuerda

 <resources xmlns:tools="http://schemas.android.com/tools">

 <string name="total_review"><b>Total Review: </b> </string>

 </resources>

y puede acceder a él desde el código java como

proDuctReviewNumber.setText(getResources().getString(R.string.total_review)+productDetailsSuccess.getProductTotalReview());
pavel
fuente
1

strings.xml

<string name="sentence">This price is <b>%1$s</b> USD</string>

page.java

String successMessage = getString(R.string.message,"5.21");

Este precio 5.21 USD

Samet ÖZTOPRAK
fuente
1
Debe utilizar la funcionalidad nativa para pasar parámetros. Simplemente coloque "% 1 $ s" en lugar de "{1}" y llame a getString (R.string.message, "5.21") sin reemplazar ()
Adrian Grygutis
Los documentos admiten esta respuesta: developer.android.com/guide/topics/resources/… Aunque debe pasar a través de un analizador HTML
ProjectDelta