it-swarm.com.de

Legen Sie TextView-Text aus einer HTML-formatierten Zeichenfolgenressource in XML fest

Ich habe einige feste Zeichenketten in meinem strings.xml, So etwas wie:

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

und in meinem layout habe ich ein TextView, das ich mit dem html-formatierten string füllen möchte.

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

wenn ich das tue, ist der Inhalt von formattedtext nur der Inhalt von somestring, der von HTML-Tags befreit und somit unformatiert ist.

Ich weiß, dass es möglich ist, den formatierten Text mit programmgesteuert einzustellen

.setText(Html.fromHtml(somestring));

weil ich dies in anderen Teilen meines Programms verwende, in denen es wie erwartet funktioniert.

Zum Aufrufen dieser Funktion benötige ich ein Activity, aber im Moment ist mein Layout nur eine einfache, mehr oder weniger statische Ansicht in einfachem XML, und ich würde es vorziehen, dies so zu belassen, um mich vor dem Overhead von zu retten Erstellen eines Activity, um nur Text festzulegen.

Übersehe ich etwas Offensichtliches? Ist das überhaupt nicht möglich? Hilfe oder Problemumgehungen sind willkommen!

Bearbeiten: Ich habe gerade einige Dinge ausprobiert und es scheint, dass die HTML-Formatierung in XML einige Einschränkungen aufweist:

  • tags müssen in Kleinbuchstaben geschrieben werden

  • einige Tags, die hier erwähnt werden , funktionieren nicht, z. <br/> (Es ist möglich, stattdessen \n Zu verwenden)

191
slup

Für den Fall, dass jemand dies findet, gibt es eine bessere Alternative, die nicht dokumentiert ist (ich habe nach stundenlangem Suchen darüber gestolpert und sie schließlich in der Fehlerliste für das Android= SDK selbst) gefunden. Sie - [~ # ~] kann [~ # ~] unformatiertes HTML in strings.xml einschließen, solange Sie es einbinden

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

Beispiel:

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

Dann in Ihrem Code:

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

IMHO, das ist mehrere Größenordnungen schöner zu arbeiten :-)

467
Bitbang3r

Da die oberste Antwort darauf hindeutet, dass etwas nicht stimmt (oder zumindest zu kompliziert), sollte dies meines Erachtens aktualisiert werden, obwohl die Frage ziemlich alt ist:

Wenn Sie String-Ressourcen in Android verwenden, müssen Sie nur getString(...) von Java code aus aufrufen oder Android:text="@string/..." In Ihrem Layout-XML verwenden.

Auch wenn Sie HTML-Markup in Ihren Strings verwenden möchten, müssen Sie nicht viel ändern:

Die einzigen Zeichen, die Sie in Ihren String-Ressourcen entziehen müssen, sind:

  • doppeltes Anführungszeichen: " wird zu \"
  • einfaches Anführungszeichen: ' wird zu \'
  • kaufmännisches Und: & wird zu &#38; oder &amp;

Das heißt, Sie können Ihr HTML-Markup hinzufügen, ohne die Tags zu maskieren :

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

Allerdings sollten Sie nur <b>, <i> Und <u> Verwenden, wie sie in der Dokumentation aufgeführt sind.

Wenn Sie Ihre HTML-Zeichenfolgen aus XML verwenden möchten, verwenden Sie einfach weiter Android:text="@string/...", Dies funktioniert problemlos.

Der einzige Unterschied besteht darin, dass Sie, wenn Sie Ihre HTML-Zeichenfolgen aus Java code verwenden möchten, getText(...) anstelle von getString(...) jetzt, da der erstere den Stil beibehält und der letztere ihn nur entfernt.

So einfach ist das. Keine CDATA, keine Html.fromHtml(...).

Sie benötigen Html.fromHtml(...) nur, wenn Sie did Ihre Sonderzeichen in HTML-Markup codieren. Verwenden Sie es dann mit getString(...). Dies kann erforderlich sein, wenn Sie den String an String.format(...) übergeben möchten.

Dies ist alles beschrieben in den Dokumenten auch.

Bearbeiten:

Es gibt keinen Unterschied zwischen getText(...) und Html.fromHtml(...) bei HTML-Abschnitten (wie ich vorgeschlagen habe) oder CDATA.

In der folgenden Grafik finden Sie einen Vergleich:

enter image description here

124
caw

Entfliehen Sie Ihren HTML-Tags ...

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

Letztes Update:

Html.fromHtml(string); // veraltet nach Android N Versionen ..

Der folgende Code unterstützt Android N und höhere Versionen ...

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));
}
10
Ranjith Kumar

Android hat keine Spezifikation, die den Typ der Ressourcenzeichenfolge angibt (z. B. text/plain oder text/html). Es gibt jedoch eine Problemumgehung, mit der der Entwickler dies in der XML-Datei angeben kann.

  1. Definieren Sie ein benutzerdefiniertes Attribut, um anzugeben, dass das Android: text-Attribut HTML ist.
  2. Verwenden Sie eine TextView-Unterklasse.

Sobald Sie diese definiert haben, können Sie sich mit HTML in XML-Dateien ausdrücken, ohne setText (Html.fromHtml (...)) erneut aufrufen zu müssen. Ich bin ziemlich überrascht, dass dieser Ansatz nicht Teil der API ist.

Diese Lösung funktioniert in dem Maße, dass der Android Studiosimulator) den Text als gerenderten HTML-Text anzeigt.

enter image description here

res/values ​​/ strings.xml (die String-Ressource als HTML)

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

layout.xml (nur die relevanten Teile)

Deklarieren Sie den Namespace für benutzerdefinierte Attribute und fügen Sie das Attribut Android_ex: isHtml hinzu. Verwenden Sie auch die Unterklasse von 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 (definieren Sie die benutzerdefinierten Attribute für die Unterklasse)

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

TextViewEx.Java (die Unterklasse von 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();
    }
}
}
10
Steven Spungin
  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);
3
Dishant Kawatra

Ich habe einen anderen Fall, in dem ich keine Chance habe, CDATA in die XML-Datei einzufügen, wenn ich die Zeichenfolge HTML von einem Server erhalte.

Folgendes bekomme ich von einem Server:

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

Es scheint komplizierter zu sein, aber die Lösung ist viel einfacher.

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

}

Ich hoffe es hilft!
Linh

2
Linh Lino