XMLのHTML形式の文字列リソースからTextViewテキストを設定する


195

私の内部にはstrings.xml、次のようないくつかの固定文字列があります。

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

私のレイアウトにはTextView、html形式の文字列で埋めたいものがありました。

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

これを行うと、のコンテンツは、htmlタグformattedtextsomestring取り除かれたため、フォーマットされていないものになります。

フォーマットされたテキストをプログラムで設定することが可能であることを知っています

.setText(Html.fromHtml(somestring));

期待どおりに機能しているプログラムの他の部分でこれを使用しているためです。

私は必要この関数を呼び出すにはActivity、現時点では私のレイアウトは、プレーンXMLでの単純な多かれ少なかれ静的な図であり、私が作成するオーバーヘッドから私を救うために、そのように残すことを好むActivityだけのいくつかを設定しますテキスト。

私は明白なものを見落としているのですか?それはまったく不可能ですか?どんなヘルプや回避策も歓迎します!

編集:いくつかのことを試してみましたが、xmlのHTMLフォーマットにはいくつかの制限があるようです:

  • タグは小文字で書く必要があります

  • ここで言及さているいくつかのタグ は機能しません、例えば<br/>\n代わりに使用することが可能です)


1
長い間知っていましたが、TextViewのhtmlを使用して、新しい行に\ nではなく<br>を使用できました。
タム

2
これはxmlだけで機能しますか?私は答えに少しの恵みがあります。この時点では、事実についての回答はすでにコーディング済みなので、私はノーと見なします。
danny117 2014

1
実際に誰も質問に答えなかったのは興味深いです。OPは、彼がfromHtml()でそれを行う方法を知っていると述べていますが、レイアウトファイルで直接実行することを望んでいます(ただし、理由はよくありません...描画している場合は、常に利用可能なアクティビティ/コンテキストがあります。スクリーン)。アンカータグの効果についても、回答はありません。
lilbyrdie

回答:


481

誰かがこれを見つけた場合に備えて、ドキュメントに記載されていないより良い代替手段があります(私は何時間も検索した後でつまずき、ついにAndroid SDK自体のバグリストで見つけました)。あなたは、CAN限り、あなたはそれを包むようのstrings.xmlで生のHTMLを含み、

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

例:

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

次に、コードで:

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

私見、これは数桁作業するのに最適です:-)


26
追加するだけで、CDATAブロック内でバックスラッシュエスケープアポストロフィ/単一引用符を使用することもできるため、無限に醜い<b> can&apos; t <の代わりに、<b>できない</ b>ことができます。 / b>
Bitbang3r

5
これはまだ機能しますか?試してみたところ、文字通り<p>と</ p>が表示されました。
Peri Hartman

1
@PeriHartmanあなたもHtml.fromHtml(getString(R.string.nice_html))ビットをしましたか?:)
非同期

1
TextView foo =(TextView)findViewById(R.id.foo);はどこにありますか?foo.setText(Html.fromHtml(getString(R.string.nice_html)))); 行く必要がありますか?
RustyIngles 2014年

2
「Html.fromHtml」を回避する方法はありますか?
Android開発者

127

ここでのトップの回答は何か間違っている(または少なくとも複雑すぎる)ことを示唆しているので、質問はかなり古いですが、これは更新する必要があると感じています。

Androidで文字列リソースをgetString(...)使用する場合android:text="@string/..."は、Javaコードから呼び出すか、レイアウトXMLで使用するだけです。

文字列でHTMLマークアップを使用する場合でも、多くを変更する必要はありません。

Stringリソースでエスケープする必要がある文字は次のとおりです。

  • 二重引用符:に"なる\"
  • 単一引用符:に'なる\'
  • アンパサンド:またはに&なる&#38;&amp;

つまり、タグをエスケープせずにHTMLマークアップを追加できます。

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

しかし、確かに、あなただけ使用する必要があり<b><i>そして<u>それらがドキュメントに記載されていて。

XMLの HTML文字列を使用したい場合は、を使い続けるだけで問題なくandroid:text="@string/..."動作します。

唯一の違いは、Javaコードから HTML文字列を使用する場合は、前者がスタイルを保持し、後者がそれを取り除くためgetText(...)getString(...)今の代わりに使用する必要があることです。

それはそれと同じくらい簡単です。CDATA、いいえHtml.fromHtml(...)

あなただけが必要になりますHtml.fromHtml(...)あなたがあればやった HTMLマークアップにあなたの特別な文字をエンコード。それでそれを使ってくださいgetString(...)。これは、文字列をに渡したい場合に必要になることがありますString.format(...)

これはすべてドキュメントにも記載されています。

編集:

getText(...)エスケープされていないHTML(私が提案したとおり)またはCDATAセクションとの間に違いはありませんHtml.fromHtml(...)

比較については、次の図を参照してください。

ここに画像の説明を入力してください


鉱山はそれを剥ぎ取っています。私は次のコードを使用しています:getResources().getText(R.string.codename)
Si8

3
より良い支援をするために、Java / XMLの抜粋を見る必要があります。しかし、私は書いた:あなたが使用している場合にのみ確認されています<b><i><u>。他のタグは常にサポートされているわけではありません。
2013年

1
あなたの答えはうまくいき、簡単です。文字列をstrings.xmlに希望のhtmlタグを付けて配置し、レイアウトxmlファイルから参照するだけです。<sup>タグを使用しました。
Peri Hartman

1
あなたのソリューションは別のソリューションであり、他のソリューションのようにすべてのタグをサポートしていないため、他のソリューションの代替手段ではありません。他のソリューションが非常に単純な場合、このソリューションには利点がありません。
mobilepotato7

1
「CDATA」を使用して経験したように、たとえば次のような問題があります。<![CDATA [... HTML ...]]>は22文字で、html部分は10です。したがって、HTML.fromhtml( getstring(...))テキストは正しく表示されますが、テキストのコンテンツには22文字のスペースが必要です。私はリストビューで使用し、雑草スペースを見ました。そのため、gettext()の方が優れています。
デビッド

16

HTMLタグをエスケープします...

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

それはドキュメントが言うことです:developer.android.com/intl/zh-TW/guide/topics/resources/… しかし、TextViewHTMLを表示するにはそれで十分ですか?
Macarse

3
私はこれをテストしましたが、Javaソースコードから使用する場合は問題ありません。しかし、レイアウトXMLから直接テキストを関連付ける場合、タグはテキストビューに表示されます(例<B>タイトル</ B> ...)
ZoltanF '28

ビューにテキストを表示するには、特に[ developer.android.com/reference/android/text/Html.html]クラスを使用しfromHTML()ます。
ekawas 2011

@ZoltanFは正しいです。HTMLのあるレイアウトからandroid:text = ""を使用すると、文字列にタグが表示されます。
Andrew Mackenzie 2013年

1
XMLから直接HTML文字列を使用する場合は、文字列にHTMLの特殊文字をエンコードしない場合があります。ただし、コードからの文字列を使用するHtml.fromHTML()場合、特殊文字エンコードする必要があります。おかしい!
CAW

11

Androidには、リソース文字列のタイプ(例:text / plainまたはtext / html)を示す仕様はありません。ただし、開発者がXMLファイル内でこれを指定できる回避策があります。

  1. カスタム属性を定義して、android:text属性がhtmlであることを指定します。
  2. サブクラス化されたTextViewを使用します。

これらを定義すると、setText(Html.fromHtml(...))を再度呼び出す必要なく、xmlファイルでHTMLを表現できます。このアプローチがAPIの一部ではないことにかなり驚いています。

このソリューションは、AndroidスタジオシミュレーターがレンダリングされたHTMLとしてテキストを表示する程度に機能します。

ここに画像の説明を入力してください

res / values / strings.xml(HTMLとしての文字列リソース)

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

layout.xml(関連する部分のみ)

カスタム属性の名前空間を宣言し、android_ex:isHtml属性を追加します。また、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(サブクラスのカスタム属性を定義)

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

TextViewEx.java(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();
    }
}
}

このアプローチの方が優れています。アプリが複数の場所でHTML形式の文字列を使用する場合は、すべての場所でHTML.fromHtmlを呼び出します。アプリ自体には、通常とHTMLの2つのビューがあります。
まんじゅう

10

最新の更新:

Html.fromHtml(string);// Android Nバージョン以降は非推奨。

次のコードは、android N以降のバージョンをサポートしています...

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

サーバーから文字列HTMLを受け取ったときにCDATAをxmlに入れる機会がない別のケースがあります。

これは私がサーバーから取得するものです:

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

より複雑に見えますが、解決策ははるかに簡単です。

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

}

それが役に立てば幸い!
リン


4
getHTMLContentFromAServer()関数の実装はどこですか
Pallavi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.