1. ホーム
  2. ハイパーリンク

[解決済み】XMLのhtml形式の文字列リソースからTextViewのテキストを設定する

2022-04-14 10:34:03

質問

の中に、いくつかの固定文字列があります。 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"/>

とすると、その内容は formattedtext の内容だけです。 somestring htmlタグを取り除いたもので、書式なし。

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

.setText(Html.fromHtml(somestring));

なぜなら、私のプログラムの他の部分でこれを使用しており、期待通りに動作しているからです。

この関数を呼び出すには Activity しかし、今のところ、私のレイアウトはプレーンなXMLのシンプルな静的ビューであり、そのままにしておきたいと思います。 Activity テキストを設定するだけです。

私は何か明らかなことを見落としているのでしょうか?全く不可能なのでしょうか?どんなヘルプや回避策も大歓迎です。

Edit: ただ、いろいろ試してみたところ、xmlのHTMLフォーマットにはいくつかの制約があるようです。

  • タグは小文字で書かなければならない

  • いくつかのタグを紹介します。 こちら は機能しません。 <br/> (を使用することは可能です)。 \n の代わりに)

解決方法は?

念のためお伝えしておきますが、文書化されていないもっと良い方法があります(私は何時間も検索して、Android SDK自体のバグリストでやっと見つけました)。あなた で囲む限り、生のHTMLをstrings.xmlに含めることができます。

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

エッジケース

  • アポストロフィ(')、ダブルクオート(")、アンパサンド(&)などの文字は、レンダリングされるテキストにそのまま表示させたい場合にのみエスケープする必要がありますが、HTMLとしてもっともらしく解釈される可能性があります。
    • '" は次のように表現できます。 \'\" または &apos;&quot; .
    • < そして > 常に としてエスケープする必要があります。 &lt;&gt; を文字どおり '<' や '>' としてレンダリングしたい場合。
    • アンパサンド(&)は少し複雑です。
      • アンパサンドの後に空白があると、アンパサンドとして描画されます。
      • アンパサンドの後に有効なHTML実体コードを形成しない1つまたは複数の文字が続くと、アンパサンドの後にそれらの文字が続くものとしてレンダリングされます。つまり... &qqq; としてレンダリングされます。 &qqq; しかし &lt;1 としてレンダリングされます。 <1 .

<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 from the same \'string\'.</p>
<p>To be clear, 0 &lt; 1, & 10 &gt; 1<p>
]]>
</string>

次に、コードに

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

IMHOでは、この方が数段作業がしやすいと思います :-)


2021年8月更新。 当初の回答ではHtml.fromHtml(String)を使用していましたが、API24で非推奨となりました。代替案として fromHtml(String,int) というフォームが提案されています。

FROM_HTML_MODE_LEGACY は動作すると思いますが、あなたがやりたいことのためには、他のフラグの方がよいかもしれません。

最後に、Android SpannedテキストをTextViewで使用するために適切なレンダリングを行うには、次のようにします。 マークダウン の構文が使えるようになり、以下のようなサードパーティライブラリで簡単に対応できるようになりました。 https://noties.io/Markwon .