TextViewでHTMLを表示する方法は?


756

私は単純なHTMLを持っています

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

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


7
タグを表示しますか、それとも省略しますか?
DerMike、2010年

1
作業例のために、このリンクをチェックアウトjavatechig.com/2013/04/07/how-to-display-html-in-android-view
Nilanchal

1
非推奨のソリューションを探しているなら、それはここにありますstackoverflow.com/questions/37904739/…–
crgarridos

回答:


1351

Html.fromHtml()XML文字列でHTML を使用するには、を使用する必要があります。レイアウト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>"));
}

7
h2定義により、それ自体の周りに多くのマージンが作成されます。そしてpまた、ある程度のマージンが付属しています。ギャップが必要ない場合は、他のhtml要素の使用を検討してください。
David Hedlund、2010年

10
Kostadin、タグをXMLに配置できます。タグをCDATAブラケットで囲む必要があります。
ジェラール

3
ol / ul / liタグを使用する場合は、次のソリューションを確認してください。stackoverflow.com/ a / 3150456/1369016
Tiago

13
それはあるはずですandroid.text.Html.fromHtml。ほとんどのIDEで修正されることはわかっていますが、読みやすくするために、パッケージ名を知っておくと便利です。
マーティン

14
@Martin 読みやすさのためではなく、徹底性のために言います。このようなコードで直接使用されるIMO完全修飾名は、短い名前よりも読みにくくなります。しかし、私はこのような答えがパッケージを提供するはずであるという事実に同意します(サイドノートに)、リンクのポイントはここにあります;)
Joffrey

76

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

4
API 24+でFROM_HTML_MODE_LEGACYを使用する理由
galcyurio

64

これを見てくださいhttps : //stackoverflow.com/a/8558249/450148

それもかなり良いです!

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

一部のタグでのみ機能します。


12
この方法でサポートされているタグのリストはありますか?
メンテ

23
@mente ソースコードによると、<a>、<b>、<big>、<blockquote>、<br>、<cite>、<dfn> <div align = "...">、<em>、< font size = "..." color = "..." face = "..."> <h1-6>、<i>、<img src = "...">、<p>、<small > <strike>、<strong>、<sub>、<sup>、<tt>、<u>(ソース:dzone.com/snippets/how-display-html-android
JerabekJakub

@JerabekJakubただし、imgを処理する場合は、Html.ImageGetterを実装する必要があります。
MiguelHincapieC、2015

@ 0mahc0がimgを実装するとき、サイズを設定することは可能ですか?
Joh

1
@Johはい、可能です。.ImageGetterを実装する場合、getDrawable(String source)というメソッドがあります。さらにヘルプが必要な場合は、質問を作成してタグを付けてください。例を挙げます;)
MiguelHincapieC

41

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

1
「...」とは 明確にしてください
GilbertS

25

文字列リソース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));

詳細については、この投稿を参照してください。


おかげで、これはAPI 23.使用ME-のためにそれをやった
XMAN

24

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

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

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

アンカーの色をどのように変更しますか?
EdmundYeung99 14

android:textColorLink = "color"
Pedro

これにより、テキストビュー全体が赤に色付けされますが、アンカータグのみが必要な場合は、<a>タグを<font>タグで
囲み

11

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

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

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


2
これは、TextViewでサポートされている制限された一連のhtmlタグを回避するのに非常に便利な方法ですが、ではうまく機能しないという欠点がありlayout_height="wrap_content"ます。代わりに、明示的な高さまたはmatch_parentを設定する必要があります。
Ridcully 2016年

3
webviewが非常に遅い
Jackky777 '26

11

次のコードスニペットがTextViewにHTMLコンテンツの実際の表示を取得するために、strings.xmlファイルの文字列にCDataセクションを使用する最良の方法は、公平なアイデアを提供します。

//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)は正常に機能し、ウェルカムメッセージに太字のテキストが表示されます。

出力:

ようこそ、お気に入りの音楽アプリストアへ。ログイン:ユーザー名


おかげで、これはAPI 23.使用ME-のためにそれをやった
XMAN

ありがとう、あなたは私の日を保存しました:)ほんの少し追加:上記のコードにこのチェックを追加する必要があります:if(Build.VERSION.SDK_INT> = Build.VERSION_CODES.N){// 24 api以上のtextView.setText( Html.fromHtml(welcomStr、Html.FROM_HTML_OPTION_USE_CSS_COLORS)); } else {//または古いAPIの場合textView.setText(Html.fromHtml(welcomStr)); } API> = 24の2番目のパラメーターフラグの値は、要件ごとに何でもかまいません。
AndroidGuy 2017


6

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

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

(new HtmlSpanner()).fromHtml()

標準のHtml.fromHtmlはレンダリングコントロールに対して十分な柔軟性を提供せず、ttfからカスタムフォントを使用する可能性もないため、私がすでにhtml to spannable converterの独自の実装によって開始した後にそれを発見しました


次のエラーが発生します:エラー:(80、13)解決できませんでした:com.osbcp.cssparser:cssparser:1.5これを解決するにはどうすればよいですか?
Araju 2017

6

この質問は古いです。他の答えはここに提案Html.fromHtml()方法があります。使用することをお勧めしますHtmlCompat.fromHtml()androidx.core.text.HtmlCompatパッケージします。これは下位互換バージョンの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のバージョンチェックを回避でき、使いやすくなります(単線ソリューション)。


それは古いmethotとどう違うのですか?HTMLモードの目的は何ですか?
user1209216

1
このようなものを探していました。ありがとう:)
Subhrajyoti Sen

5

シンプルな使い方Html.fromHtml("html string")。これは機能します。文字列がそのようなタグを持っている場合、<h1>スペースが来るでしょう。しかし、それらのスペースを排除することはできません。それでもスペースを削除したい場合は、文字列内のタグを削除してから、文字列をmethodに渡すことができますHtml.fromHtml("html string");。また、通常、これらの文字列はサーバー(動的)から取得されますが、タグを文字列から削除しようとするよりも、メソッドにそのまま渡す方が適切な場合は、そうではありません。



4

次のようなグローバルメソッドを作成します。

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

次のようにアクティビティ/フラグメントで使用することもできます。

text_view.setText(stripHtml(htmlText));

3

これを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);

UTF-8を正しく表示するには、MIMEタイプを「text / html; charset = UTF-8」に設定する必要があります。
shawkinaw

3

使用する様々な答えによって示唆されているのHTMLここで提案したようなフレームワークのクラスを、しかし、問題に示されたように、残念ながら、このクラスは、Androidの異なるバージョンの様々な取り組まれていないバグで異なる動作を持つ2146371477823512875953

したがって、互換性ライブラリを使用して、要素とスタイルのコールバックを含む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);

@MartijnPieters以前にクローズされた回答は、フレームワークメソッドの廃止に関するこの質問への回答の複製でした。互換性ライブラリを使用する方が良い方法である理由を拡張しました。どちらの質問も明確に異なるため、お互いの重複としてフラグを立てることは合理的ではないと思います。
Paul Lammertsma 2017年

2

カスタムテキストビューを作成すると、基本的なHTMLセットテキスト機能が一部のデバイスから消えてしまいます。

したがって、次の追加手順を実行する必要があります。

public class CustomTextView extends TextView {

    public CustomTextView(..) {
        // other instructions
        setText(Html.fromHtml(getText().toString()));
    }
}

1
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

以下のコードを使用してソリューションを取得します。

textView.setText(fromHtml("<Your Html Text>"))

Utitiltyメソッド

public static Spanned fromHtml(String text)
{
    Spanned result;
    if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
        result = Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY);
    } else {
        result = Html.fromHtml(text);
    }
    return result;
}

1

StringからHTMLを変換するKotlin拡張を作成-

fun String?.toHtml(): Spanned? {
    if (this.isNullOrEmpty()) return null
    return HtmlCompat.fromHtml(this, HtmlCompat.FROM_HTML_MODE_COMPACT)
}

0

ややハックですがまだ天才的な解決策を提案できますか?この記事からアイデアを得て、Androidに適合させました。基本的には、を使用してWebView、表示および編集するHTMLを編集可能なdivタグに挿入します。このようにして、ユーザーがWebViewキーボードを、キーボードが表示され、編集できるようになります。JavaScriptを追加するだけで、編集済みのHTMLを取り戻すことができます。

これがコードです:

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

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

コードが少なく、1行しかないため、Html.fromHtmlよりも優れた方法であり、推奨される使用方法です。


0

次のような単純なKotlin拡張関数を使用できます。

fun TextView.setHtmlText(source: String) {
    this.text = HtmlCompat.fromHtml(source, HtmlCompat.FROM_HTML_MODE_LEGACY)
}

そして使い方:

textViewMessage.setHtmlText("Message: <b>Hello World</b>")

0

単に使用してください:

String variable="StackOverflow";
textView.setText(Html.fromHtml("<b>Hello : </b>"+ variable));
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.