web-dev-qa-db-ja.com

TextViewでHTMLを表示する方法

私は簡単です _ html _

<h2>Title</h2><br>
<p>description here</p>

HTMLスタイルのテキストをTextViewで表示したいです。これを行う方法?

690
UMAR

XML文字列にHTMLを使用するには Html.fromHtml() を使用する必要があります。レイアウトXMLでHTMLを使用して文字列を参照するだけでは機能しません。

これはあなたがすべきことです:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    textView.setText(Html.fromHtml("<h2>Title</h2><br><p>Description here</p>", Html.FROM_HTML_MODE_COMPACT));
} else { 
    textView.setText(Html.fromHtml("<h2>Title</h2><br><p>Description here</p>"));
}
1227
David Hedlund

setText(Html.fromHtml(bodyData)) 廃止予定 api 24の後。

 if (Android.os.Build.VERSION.SDK_INT >= Android.os.Build.VERSION_CODES.N) {
      tvDocument.setText(Html.fromHtml(bodyData,Html.FROM_HTML_MODE_LEGACY));
 } else {
      tvDocument.setText(Html.fromHtml(bodyData));
 }
67

これを見てみましょう: https://stackoverflow.com/a/8558249/450148

それもかなりいいですね!

<resource>
    <string name="your_string">This is an <u>underline</u> text demo for TextView.</string>
</resources>

それはいくつかのタグに対してのみ機能します。

61
Felipe

Javaコードを変更せずにxmlを使って設定できるようにしたい場合は、このアイデアが役立つことがあります。単にコンストラクタからinitを呼び出してテキストをhtmlに設定するだけです。

public class HTMLTextView extends TextView {
    ... constructors calling init...
    private void init(){
       setText(Html.fromHtml(getText().toString()));
    }    
}

xml:

        <com.package.HTMLTextView
        Android:text="@string/about_item_1"/>
40
user1299412

以下のコードは私にとって最良の結果をもたらしました。

TextView myTextview = (TextView) findViewById(R.id.my_text_view);
htmltext = <your html (markup) character>;
Spanned sp = Html.fromHtml(htmltext);
myTextview.setText(sp);
22

文字列リソースIDからHTMLを表示しようとしている場合、フォーマットは画面に表示されないことがあります。それがあなたに起こっているのであれば、代わりにCDATAタグを使ってみてください。

strings.xml:
<string name="sample_string"><![CDATA[<h2>Title</h2><br><p>Description here</p>]]></string>

...

MainActivity.Java:
text.setText(Html.fromHtml(getString(R.string.sample_string));

詳しくは post をご覧ください。

19
Phileo99
String value = "<html> <a href=\"http://example.com/\">example.com</a> </html>";
    SiteLink= (TextView) findViewById(R.id.textViewSite);
    SiteLink.setText(Html.fromHtml(value));
    SiteLink.setMovementMethod(LinkMovementMethod.getInstance());
12
Pedro

HTMLテキストを表示したいだけで、本当にTextViewを必要としない場合は、WebViewを使用して、次のように使用します。

String htmlText = ...;
webview.loadData(htmlText , "text/html; charset=UTF-8", null);

これは、いくつかのHTMLタグにも制限されません。

11
prom85

Strings.xmlファイルの文字列にCDataセクションを使用してhtmlコンテンツをTextViewに実際に表示するには、次のコードスニペットを使用するのが最も良い方法です。

//in string.xml file
<string name="welcome_text"><![CDATA[<b>Welcome,</b> to the forthetyroprogrammers blog Logged in as:]]> %1$s.</string>

//and in Java code
String welcomStr=String.format(getString(R.string.welcome_text),username);
tvWelcomeUser.setText(Html.fromHtml(welcomStr));

文字列テキストのCDataセクションは、String.formatメソッドを使用してテキストをフォーマットした後でも、HTMLタグデータをそのまま保持します。そのため、Html.fromHtml(str)は正常に機能し、ウェルカムメッセージには太字のテキストが表示されます。

出力:

お気に入りの音楽アプリストアへようこそ。 usernameとしてログインしました。

10

言及する価値があるのは、メソッド Html.fromHtml(String source) は、APIレベル24以降では推奨されていないことです。ターゲットAPIの場合は、代わりに Html.fromHtml(String source、int flags) を使用してください。

10
Teo Inke

私はまた、次のプロジェクトを提案したいと思います: https://github.com/NightWhistler/HtmlSpanner

使い方はデフォルトのAndroidコンバータとほとんど同じです。

(new HtmlSpanner()).fromHtml()

標準のHtml.fromHtmlはレンダリング制御に対して十分な柔軟性を提供しておらず、ttfからカスタムフォントを使用することさえできないので、私がすでにhtmlからspanningableなコンバーターへの独自の実装によって始めた後にそれを見つけました。

6

簡単にHtml.fromHtml("html string")を使う。これはうまくいくでしょう。文字列に<h1>のようなタグがある場合は、スペースが入ります。しかし、それらのスペースを排除することはできません。それでもスペースを削除したい場合は、文字列内のタグを削除してから文字列をメソッドHtml.fromHtml("html string");に渡すことができます。また一般的にこれらの文字列はサーバから送られます(動的)。しかし、文字列からタグを取り除こうとするよりも文字列をそのままメソッドに渡すほうが良い場合はあまりありません。

5
java dev

以下のようにグローバルメソッドを作成します。

public static Spanned stripHtml(String html) {
            if (!TextUtils.isEmpty(html)) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    return Html.fromHtml(html, Html.FROM_HTML_MODE_COMPACT);
                } else {
                    return Html.fromHtml(html);
                }
            }
            return null;
        }

次のようにActivity/Fragmentで使用することもできます。

text_view.setText(stripHtml(htmlText));
4
Shylendra Madda
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
4
samuel gildas

ここで提案されているように Html フレームワーククラスを使用することがさまざまな回答を通じて提案されていますが、残念ながらこのクラスはAndroidの異なるバージョンで異なる動作を持ち、問題で示されているようにさまざまな未解決のバグがあります- 21463714778235128 および 7595

そのため、互換性ライブラリを使用して、要素およびスタイリングのコールバックを含むAndroidバージョン間でHtmlクラスを標準化およびバックポートすることができます。

GithubプロジェクトHtmlCompat

フレームワークのHtmlクラスに似ていますが、コールバックを増やすには署名の変更が必要でした。 GitHubページのサンプルを次に示します。

Spanned fromHtml = HtmlCompat.fromHtml(context, source, 0);
// You may want to provide an ImageGetter, TagHandler and SpanCallback:
//Spanned fromHtml = HtmlCompat.fromHtml(context, source, 0,
//        imageGetter, tagHandler, spanCallback);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(fromHtml);
3
Paul Lammertsma

私はこの質問が古いことを知っています。 Html.fromHtml() methodを提案する他の回答はここにあります。 androidx.core.text.HtmlCompatパッケージの HtmlCompat.fromHtml() を使うことをお勧めします。これはHtmlクラスの下位互換バージョンです。

サンプルコード

import androidx.core.text.HtmlCompat;
import Android.text.Spanned;
import Android.widget.TextView;

String htmlString = "<h1>Hello World!</h1>";

Spanned spanned = HtmlCompat.fromHtml(htmlString, HtmlCompat.FROM_HTML_MODE_COMPACT);

TextView tvOutput = (TextView) findViewById(R.id.text_view_id);

tvOutput.setText(spanned);

このようにすると、Android APIのバージョンチェックを避けることができ、使いやすくなります(単一行ソリューション)。

3
Shashanth

私はこれをWebビューを使って実装しました。私の場合、私はテキストビュー内のテキストと一緒にURLから画像をロードする必要があり、これは私のために動作します。

WebView myWebView =new WebView(_context);
        String html = childText;
        String mime = "text/html";
        String encoding = "utf-8";
        myWebView.getSettings().setJavaScriptEnabled(true);
        myWebView.loadDataWithBaseURL(null, html, mime, encoding, null);
3
Killer

あなたがカスタムテキストビューを書くときはいつでも、基本的なHTMLセットのテキスト機能はいくつかのデバイスから消えてしまいます。

それで、私たちは以下の追加ステップを実行する必要があります。

public class CustomTextView extends TextView {

    public CustomTextView(..) {
        // other instructions
        setText(Html.fromHtml(getText().toString()));
    }
}
2
Vinayak
public class HtmlTextView extends AppCompatTextView {

public HtmlTextView(Context context) {
    super(context);
    init();
}

private void init(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        setText(Html.fromHtml(getText().toString(), Html.FROM_HTML_MODE_COMPACT));
    } else {
        setText(Html.fromHtml(getText().toString()));
    }
 }
}

上記の回答 の更新

1
Isaac Sekamatte

多少ハックだがまだ天才的な解決策を提案してもいいですか! この記事 からアイデアを得て、それをAndroidに合わせました。基本的にはWebViewを使い、表示し編集したいHTMLを編集可能なdivタグに挿入します。これにより、ユーザーがWebViewをタップするとキーボードが表示され、編集が可能になります。編集したHTMLを元に戻すためにJavaScriptを追加するだけです。

これがコードです:

public class HtmlTextEditor extends WebView {

    class JsObject {
        // This field always keeps the latest edited text
        public String text;
        @JavascriptInterface
        public void textDidChange(String newText) {
            text = newText.replace("\n", "");
        }
    }

    private JsObject mJsObject;

    public HtmlTextEditor(Context context, AttributeSet attrs) {
        super(context, attrs);

        getSettings().setJavaScriptEnabled(true);
        mJsObject = new JsObject();
        addJavascriptInterface(mJsObject, "injectedObject");
        setWebViewClient(new WebViewClient(){
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                loadUrl(
                        "javascript:(function() { " +
                            "    var editor = document.getElementById(\"editor\");" +
                            "    editor.addEventListener(\"input\", function() {" +
                            "        injectedObject.textDidChange(editor.innerHTML);" +
                            "    }, false)" +
                            "})()");
            }
        });
    }

    public void setText(String text) {
        if (text == null) { text = ""; }

        String editableHtmlTemplate = "<!DOCTYPE html>" + "<html>" + "<head>" + "<meta name=\"viewport\" content=\"initial-scale=1.0\" />" + "</head>" + "<body>" + "<div id=\"editor\" contenteditable=\"true\">___REPLACE___</div>" + "</body>" + "</html>";
        String editableHtml = editableHtmlTemplate.replace("___REPLACE___", text);
        loadData(editableHtml, "text/html; charset=utf-8", "UTF-8");
        // Init the text field in case it's read without editing the text before
        mJsObject.text = text;
    }

    public String getText() {
        return mJsObject.text;
    }
}

そして ここ は要点としての構成要素です。

注:元のソリューションの高さ変更コールバックは必要ないので、ここでは説明しませんが、必要に応じて簡単に追加できます。

0
AXE

プロジェクトでandroidx. *クラスを使用する場合は、HtmlCompat.fromHtml(text, flag)を使用する必要があります。メソッドのソースは以下のとおりです。

@NonNull public static Spanned fromHtml(@NonNull String source, @FromHtmlFlags int flags) { if (Build.VERSION.SDK_INT >= 24) { return Html.fromHtml(source, flags); } //noinspection deprecation return Html.fromHtml(source); }

Html.fromHtmlよりも良い方法です。コードが少なく、1行しかなく、それを使用することをお勧めします。

0
pandabear