Palavras em negrito em uma string de strings.xml no Android

115

Tenho um texto longo em uma das strings em strings.xml. Quero deixar negrito e mudar a cor de algumas palavras nesse texto.

Como eu posso fazer isso?

Caroline
fonte
Você pode ser um pouco mais específico em termos do que está tentando alcançar no geral?
Brian de

Respostas:

192

Você poderia basicamente usar tags html em seu recurso de string, como:

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

E use Html.fromHtml ou use spannable, verifique o link que postei.

Antiga pergunta semelhante: É possível ter vários estilos dentro de um TextView?

David Olsson
fonte
16
Além disso, dependendo de como você usa sua string de recurso, pode ser necessário colocar as tags em negrito / itálico em um bloco CDATA para que não sejam analisadas até que sejam usadas por Html.fromHtml(): ... <![CDATA[<b><i>so</i></b>]]>...
dule
133
Para qualquer outra pessoa que achou a documentação oficial do Android um pouco vaga sobre isso: se você usar tags como <b> em seu recurso de string, certifique-se de recuperá-lo usando em getText(R.string.whatever)vez degetString(R.string.whatever)
andygeers
1
não deveria ser em namevez de id?
Hendra Anggrian
4
Portanto, não há necessidade de Html.fromHtmlou Spannable. Apenas use getText(R.string.whatever)como @andygeers mencionado.
Alaa M.
1
@andygeers O que podemos fazer para uma string como "Meu nome é <b>% s </b>", que não pode usar getText porque aceita apenas um único parâmetro?
Taylor
45

Use a tag html dentro de recursos de string: -

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

E obter texto em negrito de recursos de string 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
fonte
é a melhor resposta e funciona totalmente para as pessoas que usam @BindingAdapter. Obrigado, irmão.
Sup.Ia
44

Como David Olsson disse, você pode usar HTML em seus recursos de string:

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

Então, se você usar em getText(R.string.my_string)vez de getString(R.string.my_string)obter de volta um em CharSequencevez de um Stringque contém a formatação incorporada.

andygeers
fonte
getText retorna CharSequence não um Spannable
Tigran Babajanyan
1
E se a sua string for uma quantidade à qual você precisa adicionar um número?
Taylor
getText não permite que você use espaços reservados
Vincent_Paing
11

No kotlin, você pode criar funções de extensão em recursos (atividades | fragmentos | contexto) que converterão sua string em uma extensão html

por exemplo

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

EDITAR ainda mais extensões

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
fonte
@Himanshu Mori, algum trecho ajudaria. Você está usando na aula de kotlin?
svkaka
1
As extensões de atividades não são necessárias, a atividade é o próprio contexto
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>

Pôr

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

Você pode fazer isso com barbante

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

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

 </resources>

e pode acessá-lo a partir do código java como

proDuctReviewNumber.setText(getResources().getString(R.string.total_review)+productDetailsSuccess.getProductTotalReview());
pavel
fonte
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 preço 5,21 USD

Samet ÖZTOPRAK
fonte
1
Você deve usar a funcionalidade nativa para passar parâmetros. Basta colocar "% 1 $ s" em vez de "{1}" e chamar getString (R.string.message, "5.21") sem replace ()
Adrian Grygutis
Os documentos suportam esta resposta: developer.android.com/guide/topics/resources/… Embora precise ser passado por um analisador HTML
ProjectDelta