Imposta il testo di TextView da una risorsa stringa in formato HTML in XML


196

Ho alcune stringhe fisse all'interno della mia strings.xml, qualcosa del tipo:

<resources>
    <string name="somestring">
        <B>Title</B><BR/>
        Content
    </string>
</resources>

e nel mio layout ne ho uno TextViewche mi piacerebbe riempire con la stringa in formato HTML.

<TextView android:id="@+id/formattedtext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/htmlstring"/>

se lo faccio, il contenuto di formattedtextè solo il contenuto dello somestringstrippato di qualsiasi tag html e quindi non formattato.

So che è possibile impostare il testo formattato a livello di codice con

.setText(Html.fromHtml(somestring));

perché lo uso in altre parti del mio programma in cui funziona come previsto.

Per chiamare questa funzione ho bisogno di un Activity, ma al momento il mio layout è solo una semplice vista più o meno statica in XML semplice e preferirei lasciarlo così, per salvarmi dal sovraccarico di creare un Activitygiusto per impostare un po ' testo.

Sto trascurando qualcosa di ovvio? Non è possibile affatto? Qualsiasi aiuto o soluzioni alternative sono i benvenuti!

Modifica: ho appena provato alcune cose e sembra che la formattazione HTML in XML abbia alcune restrizioni:

  • i tag devono essere scritti in minuscolo

  • alcuni tag qui menzionati non funzionano, ad es. <br/>(è possibile utilizzare \ninvece)


1
Molto tempo ormai lo so, ma sono stato in grado di usare <br> e non \ n per una nuova linea usando l'html per un TextView.
Tam,

2
Può funzionare solo da XML? Ho una piccola ricompensa sulla risposta. Darei no come risposte concrete a questo punto che ho già scritto attorno.
danny117,

1
Trovo interessante che nessuno abbia effettivamente risposto alla domanda. L'OP afferma che sa come farlo con fromHtml (), ma vuole farlo direttamente nel file di layout (anche se, i motivi non sono buoni ... hai sempre un'attività / contesto disponibile se stai attingendo lo schermo). Nessuna delle risposte si tuffa neanche negli effetti dei tag anchor.
lilbyrdie,

Risposte:


481

Nel caso in cui qualcuno lo trovi, c'è un'alternativa più bella che non è documentata (l'ho inciampata dopo aver cercato per ore e finalmente l'ho trovata nell'elenco dei bug per l'SDK Android stesso). È POSSIBILE includere HTML grezzo in strings.xml, a patto che si avvolgono in

<![CDATA[ ...raw html... ]]>

Esempio:

<string name="nice_html">
<![CDATA[
<p>This is a html-formatted string with <b>bold</b> and <i>italic</i> text</p>
<p>This is another paragraph of the same string.</p>
]]>
</string>

Quindi, nel tuo codice:

TextView foo = (TextView)findViewById(R.id.foo);
foo.setText(Html.fromHtml(getString(R.string.nice_html)));

IMHO, ci sono diversi ordini di grandezza più belli con cui lavorare :-)


26
Solo per aggiungere, puoi anche fare il backslash-escape degli apostrofi / virgolette singole all'interno del blocco CDATA, quindi puoi avere cose come <b> non puoi </b> invece dell'infinitamente brutto <b> può & apos; t < / b>
Bitbang3r

5
Funziona ancora? L'ho appena provato e visualizza letteralmente <p> e </p>.
Peri Hartman,

1
@PeriHartman Hai anche fatto la parte Html.fromHtml(getString(R.string.nice_html))? :)
asincrono il

1
Da dove viene TextView foo = (TextView) findViewById (R.id.foo); foo.setText (Html.fromHtml (getString (R.string.nice_html))); bisogno di andare?
RustyIngles,

2
C'è un modo per evitare "Html.fromHtml"?
sviluppatore Android

128

Poiché la risposta principale qui sta suggerendo qualcosa di sbagliato (o almeno troppo complicato), penso che questo dovrebbe essere aggiornato, anche se la domanda è piuttosto vecchia:

Quando usi le risorse String in Android, devi solo chiamare getString(...)dal codice Java o utilizzare android:text="@string/..."nel tuo XML di layout.

Anche se vuoi usare il markup HTML nelle tue stringhe, non devi cambiare molto:

Gli unici caratteri che devi scappare nelle tue risorse String sono:

  • virgolette doppie: "diventa\"
  • virgolette singole: 'diventa\'
  • e commerciale: &diventa &#38;o&amp;

Ciò significa che puoi aggiungere il markup HTML senza sfuggire ai tag:

<string name="my_string"><b>Hello World!</b> This is an example.</string>

Tuttavia, per essere sicuri, si dovrebbe usare solo <b>, <i>e <u>come essi sono elencati nella documentazione.

Se vuoi usare le tue stringhe HTML da XML , continua a usare android:text="@string/...", funzionerà benissimo.

L'unica differenza è che, se si desidera utilizzare le stringhe HTML dal codice Java , è necessario utilizzare getText(...)invece di getString(...)ora, poiché il primo mantiene lo stile e il secondo lo eliminerà.

È così facile. No CDATA, noHtml.fromHtml(...) .

Avrete solo bisogno Html.fromHtml(...)se fatto codificare il caratteri speciali in HTML markup. Usalo con getString(...)allora. Questo può essere necessario se si desidera passare la stringa aString.format(...) .

Tutto ciò è anche descritto nei documenti .

Modificare:

Non c'è alcuna differenza tra getText(...)HTML senza caratteri di escape (come ho proposto) o CDATAsezioni e Html.fromHtml(...).

Vedere la seguente grafica per un confronto:

inserisci qui la descrizione dell'immagine


Il mio lo sta togliendo. Sto usando il seguente codice:getResources().getText(R.string.codename)
Si8

3
Per aiutare meglio, avrei bisogno di vedere gli estratti Java / XML. Ma, come ho scritto: Tu sei solo sicuri se si sta utilizzando <b>, <i>, <u>. Gli altri tag non sono sempre supportati.
Caw

1
La tua risposta funziona ed è semplice. Basta inserire la stringa in strings.xml, con i tag html desiderati, e fare riferimento al file XML di layout. Ho usato il tag <sup>.
Peri Hartman,

1
La tua è un'altra soluzione, non un'alternativa all'altra perché non supporta tutti i tag, come fa l'altro. Non vedo alcun vantaggio in questa soluzione quando l'altra è molto semplice.
mobilepotato7,

1
Come ho sperimentato usando "CDATA" ho un problema, qualcosa del genere per esempio: <! [CDATA [... HTML ...]]> che ha 22 lettere e la parte html ne ha 10. quindi se usi HTML.fromhtml ( getstring (...)) il testo verrà mostrato correttamente, ma il contenuto del testo necessita di spazi di 22 lettere. Ho usato in listview e ho visto spazi erbosi. quindi gettext () è MEGLIO.
David,

16

Esci dai tag HTML ...

<resources>
    <string name="somestring">
        &lt;B&gt;Title&lt;/B&gt;&lt;BR/&gt;
        Content
    </string>
</resources>

Questo è ciò che dicono i documenti: developer.android.com/intl/zh-TW/guide/topics/resources/… ma è abbastanza per TextViewmostrare HTML?
Macarse,

3
Ho provato questo, e se lo usi dal codice sorgente Java, va bene. Ma se associ il tuo testo direttamente dall'XML del layout, i tag vengono visualizzati nella vista di testo (ad es. <B> Titolo </B> ...)
ZoltanF,

Per mostrare il testo in una vista, utilizzare la classe [ developer.android.com/reference/android/text/Html.html] , in particolare fromHTML().
Ekawas

@ZoltanF ha ragione, usando android: text = "" da un layout con HTML mostrerà i tag nella stringa.
Andrew Mackenzie,

1
Se si desidera utilizzare la stringa HTML direttamente da XML, si può non HTML codificare i caratteri speciali nella stringa. Tuttavia, se si desidera utilizzare la stringa dal codice tramite, Html.fromHTML()è necessario codificare i caratteri speciali. Strano!
Caw

11

Android non ha una specifica per indicare il tipo di stringa di risorse (ad es. Text / plain o text / html). Esiste tuttavia una soluzione alternativa che consentirà allo sviluppatore di specificarlo nel file XML.

  1. Definire un attributo personalizzato per specificare che l'attributo android: text è html.
  2. Utilizzare un oggetto TextView sottoclasse.

Dopo averli definiti, puoi esprimerti con HTML in file xml senza dover chiamare nuovamente setText (Html.fromHtml (...)). Sono piuttosto sorpreso che questo approccio non faccia parte dell'API.

Questa soluzione funziona nella misura in cui il simulatore di studio Android visualizzerà il testo come HTML renderizzato.

inserisci qui la descrizione dell'immagine

res / valori / strings.xml (la risorsa stringa come HTML)

<resources>
<string name="app_name">TextViewEx</string>
<string name="string_with_html"><![CDATA[
       <em>Hello</em> <strong>World</strong>!
 ]]></string>
</resources>

layout.xml (solo le parti pertinenti)

Dichiarare lo spazio dei nomi dell'attributo personalizzato e aggiungere l'attributo android_ex: isHtml. Utilizzare anche la sottoclasse di TextView.

<RelativeLayout
...
xmlns:android_ex="http://schemas.android.com/apk/res-auto"
...>

<tv.twelvetone.samples.textviewex.TextViewEx
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/string_with_html"
    android_ex:isHtml="true"
    />
 </RelativeLayout>

res / valori / attrs.xml (definire gli attributi personalizzati per la sottoclasse)

 <resources>
<declare-styleable name="TextViewEx">
    <attr name="isHtml" format="boolean"/>
    <attr name="android:text" />
</declare-styleable>
</resources>

TextViewEx.java (la sottoclasse di TextView)

 package tv.twelvetone.samples.textviewex;

 import android.content.Context;
 import android.content.res.TypedArray;
 import android.support.annotation.Nullable;
 import android.text.Html;
 import android.util.AttributeSet;
 import android.widget.TextView;

public TextViewEx(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextViewEx, 0, 0);
    try {
        boolean isHtml = a.getBoolean(R.styleable.TextViewEx_isHtml, false);
        if (isHtml) {
            String text = a.getString(R.styleable.TextViewEx_android_text);
            if (text != null) {
                setText(Html.fromHtml(text));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        a.recycle();
    }
}
}

Questo approccio sarà migliore, se l'app utilizza stringhe in formato HTML in più punti anziché chiamare HTML.fromHtml in ogni luogo. L'app stessa avrà due viste una per normale e una per HTML.
Manju,

10

Ultimo aggiornamento:

Html.fromHtml(string);// obsoleto dopo le versioni di Android N ..

Il codice seguente supporta Android N e versioni successive ...

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
textView.setText(Html.fromHtml(yourHtmlString,Html.FROM_HTML_MODE_LEGACY));
}

else 
{
textView.setText(Html.fromHtml(yourHtmlString));
}

3
  String termsOfCondition="<font color=#cc0029>Terms of Use </font>";
  String commma="<font color=#000000>, </font>";
  String privacyPolicy="<font color=#cc0029>Privacy Policy </font>";
  Spanned text=Html.fromHtml("I am of legal age and I have read, understood, agreed and accepted the "+termsOfCondition+commma+privacyPolicy);
        secondCheckBox.setText(text);

2

Ho un altro caso in cui non ho alcuna possibilità di inserire CDATA nel file XML quando ricevo la stringa HTML da un server.

Ecco cosa ottengo da un server:

<p>The quick brown&nbsp;<br />
fox jumps&nbsp;<br />
 over the lazy dog<br />
</p>

Sembra essere più complicato ma la soluzione è molto più semplice.

private TextView textView;

protected void onCreate(Bundle savedInstanceState) { 
.....
textView = (TextView) findViewById(R.id.text); //need to define in your layout
String htmlFromServer = getHTMLContentFromAServer(); 
textView.setText(Html.fromHtml(htmlFromServer).toString());

}

Spero che sia d'aiuto!
Linh


4
dov'è l'implementazione della funzione getHTMLContentFromAServer ()
Pallavi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.