Définissez le texte de TextView à partir de la ressource de chaîne de caractères formatée en html dans XML

j'ai des cordes fixes à l'intérieur de mon strings.xml , quelque chose comme:

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

et dans ma mise en page j'ai un TextView que j'aimerais remplir avec la chaîne HTML-formatée.

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

si je fais cela, le contenu de formattedtext est juste le contenu de somestring dépouillé de toute étiquette html et donc non formaté.

je sais qu'il est possible de programmer le texte formaté avec

.setText(Html.fromHtml(somestring));

parce que je l'utilise dans d'autres parties de mon programme où il fonctionne comme prévu.

pour appeler cette fonction j'ai besoin d'un Activity , mais pour le moment ma mise en page est juste une simple vue plus ou moins statique en XML simple et je préférerais la laisser de cette façon, pour me sauver de la surabondance de créer un Activity juste pour mettre un peu de texte.

est-ce que j'oublie quelque chose évident? N'est-il pas possible? Toute aide ou solution de Rechange bienvenue!

Edit: Juste essayé certaines choses, et il semble que la mise en forme HTML en xml a quelques contraintes:

  • les balises doivent être écrites en minuscules

  • certaines étiquettes qui sont mentionnées ici ne fonctionnent pas, par exemple <br/> (il est possible d'utiliser n à la place)

182
demandé sur Community 2010-07-13 11:51:10

6 réponses

juste au cas où quelqu'un trouve ceci, il y a une alternative plus sympa qui n'est pas documentée (j'ai trébuché dessus après avoir cherché pendant des heures, et je l'ai finalement trouvé dans la liste des bugs pour le SDK Android lui-même). Vous CAN incluez du HTML brut dans les chaînes.xml, aussi longtemps que vous l'enveloppez dans

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

exemple:

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

puis, dans votre code:

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

IMHO, ici plusieurs ordres de grandeur plus agréable à travailler avec: -)

451
répondu Bitbang3r 2011-05-28 03:52:44

comme la meilleure réponse ici est de suggérer quelque chose de mal (ou du moins trop compliqué), je pense que cela devrait être mis à jour, bien que la question est assez ancienne:

lorsque vous utilisez des ressources de chaîne de caractères sur Android, vous n'avez qu'à appeler getString(...) à partir du code Java ou à utiliser android:text="@string/..." dans votre mise en page XML.

même si vous voulez utiliser HTML markup dans vos chaînes, vous n'avez pas à changer beaucoup:

les seuls caractères dont vous avez besoin pour échapper à vos ressources String sont:

  • double guillemet: " devient \"
  • simple guillemet: ' devient \'
  • esperluette: & devient &#38; ou &amp;

cela signifie que vous pouvez ajouter votre HTML sans échapper les tags:

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

cependant, pour être sûr, vous ne devez utiliser <b> , <i> et <u> car ils sont énumérés dans la documentation.

si vous voulez utiliser vos chaînes HTML de XML , il suffit de continuer à utiliser android:text="@string/..." , il fonctionnera très bien.

la seule différence est que, si vous voulez utiliser vos chaînes HTML du code Java , vous devez utiliser getText(...) au lieu de getString(...) maintenant, car le premier garde le style et le second juste le dépouiller.

C'est aussi simple que cela. Pas de CDATA, pas de Html.fromHtml(...) .

vous n'aurez besoin de Html.fromHtml(...) que si vous did encodez vos caractères spéciaux dans le markup HTML. Utilisez-le avec getString(...) alors. Cela peut être nécessaire si vous souhaitez passer la Chaîne à String.format(...) .

This est tout décrit dans les docs ainsi.

Edit:

il n'y a pas de différence entre getText(...) avec des sections HTML (comme je l'ai proposé) ou CDATA et Html.fromHtml(...) .

voir le graphique suivant pour une comparaison:

enter image description here

113
répondu caw 2016-06-01 10:48:26

échappez à vos balises HTML ...

<resources>
    <string name="somestring">
        &lt;B&gt;Title&lt;/B&gt;&lt;BR/&gt;
        Content
    </string>
</resources>
15
répondu ekawas 2010-07-13 13:07:08

Android n'a pas de spécification pour indiquer le type de chaîne de ressource (par exemple text/plain ou text/html). Il y a une solution de rechange, cependant, qui permettra au développeur de spécifier ceci dans le fichier XML.

  1. définit un attribut personnalisé pour spécifier que l'attribut android:text est html.
  2. utilisez un TextView sous-classé.

une fois que vous les définissez, vous pouvez vous exprimer avec HTML en les fichiers xml sans jamais avoir à appeler setText (Html.fromHtml(...)) encore. Je suis plutôt surpris que cette approche ne fasse pas partie de L'API.

cette solution fonctionne dans la mesure où le simulateur Android studio affichera le texte tel que rendu HTML.

enter image description here

res/values/cordes.xml (la ressource de chaîne au format HTML)

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

mise en page.xml (seulement les parties pertinentes)

déclare l'espace de nom de l'attribut personnalisé, et ajoute l'attribut android_ex:isHtml. Utilisez également la sous-classe de 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/values / attrs.xml (définir les attributs personnalisés pour la sous-classe)

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

TextViewEx.java (la sous-classe de 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();
    }
}
}
7
répondu Steven Spungin 2016-09-22 04:16:14

dernière mise à jour:

Html.fromHtml (string);//déprécié après les versions Android N..

Le code suivant

supporte android N et les versions supérieures...

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));
}
7
répondu Ranjith Kumar 2016-11-22 14:51:10

j'ai un autre cas où je n'ai aucune chance de mettre CDATA dans le xml que je reçois la chaîne HTML d'un serveur.

voici ce que j'obtiens d'un serveur:

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

cela semble plus compliqué mais la solution est beaucoup plus simple.

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

}

Espère que cela aide!

Linh

2
répondu Linh Lino 2015-12-24 02:50:54