情報もそこそこあるし楽勝と思いきや、悪戦苦闘になったため、ハマった点を書いておきます。
主に Html#fromHtml() の話です。
グーグル先生に
「TextViewにHTMLを表示させるにはどうしたらいい?」
と聞くと、
「android.text.Html#fromHtml()を使んだよ」
と教えてくれます。
でも、実はちょっと違います。
「TextViewに書式付きでテキストを表示させるなら、android.text.Html#fromHtml()を使うと手っ取り早い」
が正しいです。
どういうことかと言うと、Html#fromHtml()は制限が多すぎて、そこらにあるナマのHTMLを読み込ませても、ほとんどうまくいきません。
私が困ったことに限っても、ざっとこんな感じ。
- 処理できるタグの数が限られる
特に、取り消し線の<strike><s>や、<span>、<ul><ol><li>のリスト関係、<table>関係がサポートされていません。
またタグだけでなく、属性もものすごく限られてます。<font>のfaceとcolorのみ。
今どき、表示に関するものはほとんどstyle属性であろうに、それは総スルーです。 - 処理されないタグは自分で扱えるには扱えるが、属性を見られない
サポートされていないタグについては、それらのタグを処理するTagHandlerを自前で用意して引数に渡すと、一応処理できますが、そのTagHandler#handleTag内で要素の属性にアクセスする手段が提供されていません。 - 処理されるタグは一切触れられない
<div>や<p>は独自ルールで改行に置き換えられ、それらが持つ属性に触れる機会は一切与えられません。 - 入れ子に対応できない
文字の色は
<font color="#ff0000">赤</font>
とでもすれば、ちゃんと赤が反映されますが、例えば
<font color="#ff0000">赤<font color="#0000ff">青<font color="#0000ff">緑</font></font>色</font>
とすると、赤青緑色じゃなく、赤青緑色になります。
そんなわけで、シンプルなHTMLに使うか、どう表示させたいかがあって、自前でHTMLの文字列を作らないと使えないメソッドです。
まあ、それもそのはず。
普通HTMLを表示しようとしたら、TextViewじゃなくWebViewを使います。
だからTextViewでがんばる必要は無いのです。
しかし。ウィジェットになると話は別です。
ウィジェットにできるViewもまた制限があって、WebViewは使えません。
なので、ホーム画面にテキストを表示しようとすると、やはりTextViewになります。
だからTextViewでがんばる必要があるのです。
で、どうがんばったかというと、ざっとこんな感じ。番号は上の番号と対応してます。
- Evernoteのコンテンツ(XHTMLをベースにしたENML形式のテキスト)をHtml#fromHtml()がなるべく読めるHTMLに変換。
- 変換したHTMLをHtml#fromHtml()で処理。このとき、自前のTagHandlerでサポート外のタグを処理。属性はリフレクションを使って強引に参照。
- <div>はEvernoteだと頻繁に使われて、改行されすぎになったりするから、<span>に置き換えて、自前のTagHandlerで扱えるように。
- 文字色の入れ子は、子の色が出て来たところで親の色をスタックに退避し、子の色が終ったら親の色を再開することで対応。
とまあ、なかなかの力技ですが、なんとかそれなりに表示できるようになりました。
こんなことは、やるもんじゃないです。
0 件のコメント:
コメントを投稿