Bagaimana cara menampilkan HTML di TextView?

757

Saya punya HTML sederhana :

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

Saya ingin menampilkan teks dengan gaya HTML TextView. Bagaimana cara melakukannya?

UMAR
sumber
7
Apakah Anda ingin menampilkan tag atau menghilangkannya?
DerMike
1
lihat tautan ini untuk contoh kerja javatechig.com/2013/04/07/how-to-display-html-in-android-view
Nilanchal
1
Jika Anda mencari solusi yang sudah usang, itu ada di sini saja stackoverflow.com/questions/37904739/…
crgarridos

Jawaban:

1352

Anda harus menggunakan Html.fromHtml() untuk menggunakan HTML di XML Strings Anda. Cukup mereferensikan sebuah String dengan HTML di layout Anda XML tidak akan berfungsi.

Inilah yang harus Anda lakukan:

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>"));
}
Johnny Five
sumber
7
h2menurut definisi menciptakan banyak margin di sekitar dirinya sendiri. dan pjuga dilengkapi dengan beberapa margin. jika Anda tidak ingin celahnya, Anda mungkin ingin mempertimbangkan untuk menggunakan elemen html lainnya.
David Hedlund
10
Kostadin, Anda dapat menempatkan tag dalam XML, Anda hanya perlu membungkusnya dalam tanda kurung CDATA.
Gerard
3
Bagi mereka yang ingin bekerja dengan tag ol / ul / li, lihat solusi ini: stackoverflow.com/a/3150456/1369016
Tiago
14
Itu seharusnya android.text.Html.fromHtml. Saya tahu sebagian besar IDE akan memperbaikinya untuk Anda tetapi untuk keterbacaan itu lebih baik untuk mengetahui nama paket.
Martin
14
@ Martin Saya tidak akan mengatakan untuk keterbacaan tetapi lebih untuk kelengkapan . IMO nama yang sepenuhnya memenuhi syarat yang digunakan langsung dalam kode seperti ini kurang dapat dibaca daripada nama pendek. Tapi saya setuju dengan Anda pada kenyataan bahwa jawaban seperti ini harus menyediakan paket (pada catatan), yang mana titik tautannya di sini;)
Joffrey
76

setText (Html.fromHtml (bodyData)) tidak digunakan lagi setelah api 24. Sekarang Anda harus melakukan ini:

 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));
 }
Shohan Ahmed Sijan
sumber
4
Mengapa menggunakan FROM_HTML_MODE_LEGACY di API 24+?
galcyurio
64

Lihat ini: https://stackoverflow.com/a/8558249/450148

Cukup bagus juga !!

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

Ini hanya berfungsi untuk beberapa tag.

Felipe Micaroni Lalli
sumber
12
Apakah ada daftar tag yang didukung oleh metode ini?
mente
23
@mente Menurut kode sumber : <a>, <b>, <big>, <blockquote>, <br>, <cite>, <dfn> <div align = "...">, <em>, < font size = "..." color = "..." face = "..."> <h1-6>, <i>, <img src = "...">, <p>, <kecil > <strike>, <strong>, <sub>, <sup>, <tt>, <u> (sumber: dzone.com/snippets/how-display-html-android )
JerabekJakub
@JerabekJakub tapi hati-hati, jika Anda akan menangani img Anda harus mengimplementasikan Html.ImageGetter.
MiguelHincapieC
@ 0mahc0 ketika seseorang mengimplementasikan img apakah mungkin untuk mengatur ukuran?
Joh
1
@ John ya itu mungkin. Ketika Anda menerapkan .ImageGetter, ada metode yang disebut getDrawable (sumber String). Jika Anda memerlukan bantuan lebih lanjut, buat pertanyaan dan beri tag saya, saya akan memberikan Anda sebuah contoh;)
MiguelHincapieC
41

Jika Anda ingin dapat mengkonfigurasinya melalui xml tanpa ada modifikasi dalam kode java Anda mungkin menemukan ide ini bermanfaat. Cukup Anda memanggil init dari konstruktor dan mengatur teks sebagai 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"/>
pengguna1299412
sumber
1
Apa itu ... Mohon klarifikasi
GilbertS
25

Jika Anda mencoba menampilkan HTML dari id sumber daya string, pemformatan mungkin tidak muncul di layar. Jika itu terjadi pada Anda, coba gunakan tag CDATA sebagai gantinya:

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

Lihat posting ini untuk detail lebih lanjut.

Phileo99
sumber
Terima kasih, ini berhasil untuk saya - menggunakan API 23.
XMAN
24

Kode di bawah ini memberikan hasil terbaik untuk saya.

TextView myTextview = (TextView) findViewById(R.id.my_text_view);
htmltext = <your html (markup) character>;
Spanned sp = Html.fromHtml(htmltext);
myTextview.setText(sp);
Rajiv Manivannan
sumber
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());
Pedro
sumber
bagaimana Anda mengubah warna jangkar?
Edmund Yeung99
android: textColorLink = "color"
Pedro
ini akan mewarnai seluruh tampilan teks menjadi merah, tetapi jika saya hanya ingin tag jangkar, saya harus membungkus tag <a> dengan <i> tag dan menambahkan warna di sana
EdmundYeung99
11

Jika Anda hanya ingin menampilkan beberapa teks html dan tidak benar-benar membutuhkan TextView, maka ambil WebViewdan gunakan seperti berikut:

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

Ini tidak membatasi Anda untuk beberapa tag html juga.

prom85
sumber
2
Meskipun ini adalah cara yang sangat berguna untuk menyiasati kumpulan tag html terbatas, didukung oleh TextView, ini memiliki kelemahan yang tidak berfungsi dengan baiklayout_height="wrap_content" . Anda harus menetapkan tinggi eksplisit atau match_parent sebagai gantinya.
Ridcully
3
tampilan
11

Pendekatan terbaik untuk menggunakan bagian CData untuk string dalam file strings.xml untuk mendapatkan tampilan aktual dari konten html ke TextView potongan kode di bawah ini akan memberi Anda ide yang adil.

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

Bagian CData dalam teks string menjaga data tag html tetap utuh bahkan setelah memformat teks menggunakan metode String.format. Jadi, Html.fromHtml (str) berfungsi dengan baik dan Anda akan melihat teks tebal di pesan Selamat Datang.

Keluaran:

Selamat datang, di toko aplikasi musik favorit Anda. Masuk sebagai: nama pengguna

Rajendhiran Easu
sumber
Terima kasih, ini berhasil untuk saya - menggunakan API 23.
XMAN
terima kasih, kamu menyelamatkan hariku :) Hanya tambahan kecil: Kita perlu menambahkan tanda centang ini ke kode di atas: if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.N) {// untuk 24 api dan lebih banyak textView.setText ( Html.fromHtml (welcomStr, Html.FROM_HTML_OPTION_USE_CSS_COLORS)); } else {// atau untuk api textView.setText (Html.fromHtml (welcomStr)) yang lebih lama; }. Nilai untuk flag parameter ke-2 untuk API> = 24, dapat berupa apa saja sesuai kebutuhan.
AndroidGuy
6

Saya juga ingin menyarankan proyek berikut: https://github.com/NightWhistler/HtmlSpanner

Penggunaannya hampir sama dengan konverter android default:

(new HtmlSpanner()).fromHtml()

Menemukannya setelah saya sudah mulai dengan implementasi sendiri html ke spannable converter, karena standar Html.fromHtml tidak memberikan fleksibilitas yang cukup atas kontrol rendering dan bahkan tidak ada kemungkinan untuk menggunakan font khusus dari ttf

Fedotchenco Denis
sumber
Saya mendapatkan kesalahan sebagai berikut: Kesalahan: (80, 13) Gagal menyelesaikan: com.osbcp.cssparser: cssparser: 1.5 Bagaimana cara mengatasi ini?
Araju
6

Saya tahu pertanyaan ini sudah tua. Jawaban lain di sini menyarankan Html.fromHtml()metode. Saya sarankan Anda untuk menggunakan HtmlCompat.fromHtml()dari androidx.core.text.HtmlCompatpaket. Karena ini adalah versi yang kompatibel ke belakangHtml kelas yang .

Kode sampel:

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

Dengan cara ini Anda dapat menghindari pemeriksaan versi Android API dan mudah digunakan (solusi single line).

Shashanth
sumber
Bagaimana itu berbeda dari methot lama? Apa tujuan mode html?
user1209216
1
Sedang mencari sesuatu seperti ini. Terima kasih :)
Subhrajyoti Sen
5

Penggunaan sederhana Html.fromHtml("html string"). Ini akan bekerja Jika string memiliki tag seperti <h1>maka spasi akan datang. Tapi kita tidak bisa menghilangkan ruang itu. Jika Anda masih ingin menghapus spasi, maka Anda dapat menghapus tag di string dan kemudian meneruskan string ke metode Html.fromHtml("html string");. Juga umumnya string ini berasal dari server (dinamis) tetapi tidak sering, jika ini adalah kasus yang lebih baik untuk meneruskan string seperti metode, daripada mencoba untuk menghapus tag dari string.

nole
sumber
4
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
samuel gildas
sumber
4

Buat metode global seperti:

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

Anda juga dapat menggunakannya di Aktivitas / Fragmen Anda seperti:

text_view.setText(stripHtml(htmlText));
Shylendra Madda
sumber
3

Saya telah menerapkan ini menggunakan tampilan web. Dalam kasus saya, saya harus memuat gambar dari URL bersama dengan teks dalam tampilan teks dan ini berfungsi untuk saya.

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);
Pembunuh
sumber
Untuk tampilan UTF-8 yang tepat, Anda perlu mengatur tipe MIME menjadi "text / html; charset = UTF-8".
shawkinaw
3

Telah disarankan melalui berbagai jawaban untuk menggunakan kelas kerangka kerja Html seperti yang disarankan di sini, tetapi sayangnya kelas ini memiliki perilaku yang berbeda di berbagai versi Android dan berbagai bug yang belum diperbaiki , seperti yang ditunjukkan dalam edisi 214637 , 14778 , 235128 , dan 75953 .

Karena itu, Anda mungkin ingin menggunakan pustaka kompatibilitas untuk menstandarkan dan mendukung kelas Html di versi Android yang mencakup lebih banyak panggilan balik untuk elemen dan gaya:

Proyek Github HtmlCompat

Meskipun mirip dengan kelas Html framework, beberapa perubahan tanda tangan diperlukan untuk memungkinkan lebih banyak panggilan balik. Berikut contoh dari halaman 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);
Paul Lammertsma
sumber
@ MartijnPieters Jawaban yang sebelumnya ditutup adalah duplikat dari jawaban untuk pertanyaan ini sehubungan dengan penghentian metode kerangka kerja . Saya telah memperluas alasan menggunakan perpustakaan kompatibilitas akan menjadi pendekatan yang lebih baik. Saya pikir tidak masuk akal untuk menandai kedua pertanyaan sebagai duplikat satu sama lain karena keduanya jelas berbeda.
Paul Lammertsma
2

Setiap kali Anda menulis tampilan teks kustom fitur HTML set teks dasar akan hilang dari beberapa perangkat.

Jadi kita perlu melakukan langkah-langkah tambahan berikut agar berfungsi

public class CustomTextView extends TextView {

    public CustomTextView(..) {
        // other instructions
        setText(Html.fromHtml(getText().toString()));
    }
}
Vinayak
sumber
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()));
    }
 }
}

pembaruan jawaban di atas

Isaac Sekamatte
sumber
1

Gunakan kode di bawah ini untuk mendapatkan solusinya:

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

Metode 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;
}
Somesh Kumar
sumber
1

Membuat ekstensi Kotlin untuk mengonversi html dari String -

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

Bolehkah saya menyarankan solusi yang agak aneh tapi tetap jenius! Saya mendapat ide dari artikel ini dan mengadaptasinya untuk Android. Pada dasarnya Anda menggunakan WebViewdan memasukkan HTML yang ingin Anda tampilkan dan edit dalam tag div yang dapat diedit. Dengan cara ini saat pengguna mengetuk tombolWebView keyboard muncul dan memungkinkan pengeditan. Mereka Anda baru saja menambahkan beberapa JavaScript untuk mendapatkan kembali HTML dan voila yang diedit!

Ini kodenya:

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

Dan di sini adalah komponen sebagai Intisari.

Catatan: Saya tidak memerlukan panggilan balik perubahan tinggi dari solusi asli sehingga tidak ada di sini tetapi Anda dapat dengan mudah menambahkannya jika diperlukan.

AX
sumber
0

Jika Anda menggunakan androidx.* kelas dalam proyek Anda, Anda harus menggunakan HtmlCompat.fromHtml(text, flag). Sumber metode adalah:

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

Ini adalah cara yang lebih baik daripada Html.fromHtml karena ada lebih sedikit kode, hanya satu baris, dan cara yang disarankan untuk menggunakannya.

Beruang panda
sumber
0

Anda dapat menggunakan fungsi ekstensi Kotlin sederhana seperti ini:

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

Dan penggunaan:

textViewMessage.setHtmlText("Message: <b>Hello World</b>")
seyfullah.bilgin
sumber
0

Cukup gunakan:

String variable="StackOverflow";
textView.setText(Html.fromHtml("<b>Hello : </b>"+ variable));
Sumit Shukla
sumber