TextView'da HTML nasıl görüntülenir?


756

Basit HTML kodum var :

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

İçinde HTML tarzında metin görüntülemek istiyorum TextView. Bu nasıl yapılır?


7
Etiketleri görüntülemek mi yoksa atlamak mı istiyorsunuz?
DerMike

1
çalışma örneği için bu bağlantıya göz atın javatechig.com/2013/04/07/how-to-display-html-in-android-view
Nilanchal

1
Kullanımdan kaldırılmış bir çözüm arıyorsanız, tam burada stackoverflow.com/questions/37904739/…
crgarridos

Yanıtlar:


1350

Html.fromHtml()XML Dizelerinizde HTML kullanmak için kullanmanız gerekir . Düzen XML'nizde HTML içeren bir Dizeye başvurmanız işe yaramaz.

Yapmanız gerekenler:

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
h2tanımı gereği kendi etrafında çok fazla marj yaratır. ve payrıca bir miktar marjla birlikte gelir. boşluğu istemiyorsanız, diğer html öğelerini kullanmayı düşünebilirsiniz.
David Hedlund

10
Kostadin, etiketleri XML olarak koyabilirsiniz, bunları CDATA parantezlerine sarmanız yeterlidir.
Gerard

3
Ol / ul / li etiketleriyle çalışmasını isteyenler için şu çözümü inceleyin: stackoverflow.com/a/3150456/1369016
Tiago

13
Öyle olmalı android.text.Html.fromHtml. Çoğu IDE'nin sizin için düzelteceğini biliyorum, ancak okunabilirlik için paket adlarını bilmek daha güzel.
Martin

14
Ben öyle demezdim @Martin okunabilmesi için değil, exhaustivity için . Bunun gibi doğrudan kodda kullanılan IMO tam nitelikli adları kısa adlardan daha az okunabilir. Ancak, bu tür bir cevabın, burada bağlantının noktası olan paketi (bir yan notta) sağlaması gerektiği konusunda size katılıyorum;)
Joffrey

76

setText (Html.fromHtml (bodyData)) olduğu kaldırılmış Artık bunu yapmak zorunda API 24. sonrası:

 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+ sürümünde neden FROM_HTML_MODE_LEGACY kullanılıyor?
galcyurio

64

Şuna bir göz atın: https://stackoverflow.com/a/8558249/450148

Çok iyi !!

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

Yalnızca birkaç etiket için çalışır.


12
Bu yöntemle desteklenen etiket listesi var mı?
mente

23
@mente Kaynak kodlarına göre : <a>, <b>, <big>, <blockquote>, <br>, <cite>, <dfn> <div align = "...">, <em>, < font size = "..." color = "..." face = "..."> <h1-6>, <i>, <img src = "...">, <p>, <küçük > <strike>, <strong>, <sub>, <sup>, <tt>, <u> (kaynak: dzone.com/snippets/how-display-html-android )
JerabekJakub

@JerabekJakub ama dikkat edin, eğer img ile başlayacaksanız Html.ImageGetter uygulamanız gerekir.
MiguelHincapieC

@ 0mahc0 img uygulandığında boyutu ayarlamak mümkün mü?
Joh

1
@ Evet evet mümkün. .ImageGetter uygularken getDrawable (String source) adlı bir yöntem vardır. Daha fazla yardıma ihtiyacınız varsa, bir soru oluşturun ve beni etiketleyin, size bir örnek vereceğim;)
MiguelHincapieC

41

Java kodunda herhangi bir değişiklik yapmadan xml ile yapılandırabilmek istiyorsanız bu fikri yararlı bulabilirsiniz. Yapıcıdan init'i çağırmanız ve metni html olarak ayarlamanız yeterlidir

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
'...' nedir. Lütfen açıklayın
GilbertS

25

Bir dize kaynak kimliğinden HTML göstermeye çalışıyorsanız, biçimlendirme ekranda görünmeyebilir. Bu gerçekleşiyorsa, bunun yerine CDATA etiketlerini kullanmayı deneyin:

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

Daha fazla ayrıntı için bu gönderiye bakın.


Teşekkürler, bu benim için yaptı
XMAN

24

Aşağıdaki kod benim için en iyi sonucu verdi.

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

çapanın rengini nasıl değiştirirsiniz?
EdmundYeung99

android: textColorLink = "renk"
Pedro

Bu, tüm metin görünümünü kırmızıya renklendirir, ancak yalnızca bağlantı etiketlerini istiyorsam, <a> etiketini <font> etiketleriyle
sarmalı

11

Sadece bazı html metinlerini görüntülemek istiyorsanız ve gerçekten a'ya ihtiyacınız yoksa TextView, a'yı alıp WebViewaşağıdaki gibi kullanın:

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

Bu, sizi birkaç html etiketi ile sınırlamaz.


2
Bu, TextView tarafından desteklenen sınırlı html etiketleri kümesini aşmanın çok yararlı bir yolu olsa da, iyi çalışmadığı dezavantajlara sahiptir layout_height="wrap_content". Bunun yerine açık bir yükseklik veya match_parent ayarlamanız gerekir.
ridcully at

3

11

Html içeriğinin TextView'e gerçek bir görüntüsünü almak için dizeler için CData bölümlerini kullanmak için en iyi yaklaşım Aşağıdaki kod snippet'i size adil bir fikir verecektir.

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

Dize metnindeki CData bölümü, String.format yöntemini kullanarak metni biçimlendirdikten sonra bile html etiketi verilerini korur. Html.fromHtml (str) iyi çalışır ve Hoş Geldiniz iletisinde kalın metni görürsünüz.

Çıktı:

En sevdiğiniz müzik uygulaması mağazasına hoş geldiniz. Giriş tarihi: kullanıcı adı


Teşekkürler, bu benim için yaptı
XMAN

teşekkürler, u günümü kurtardı :) Sadece küçük bir ek: Bu kodu yukarıdaki koda eklememiz gerekiyor: if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.N) {// 24 api ve daha fazlası için textView.setText ( Html.fromHtml (welcomStr, Html.FROM_HTML_OPTION_USE_CSS_COLORS)); } else {// veya daha eski api textView.setText (Html.fromHtml (welcomStr)); }. API> = 24 için 2. parametre bayrağının değeri, gereksinime göre herhangi bir şey olabilir.
AndroidGuy


6

Ayrıca aşağıdaki projeyi önermek istiyorum: https://github.com/NightWhistler/HtmlSpanner

Kullanımı neredeyse varsayılan android dönüştürücü ile aynıdır:

(new HtmlSpanner()).fromHtml()

Standart Html.fromHtml, render denetimi üzerinde yeterli esneklik sağlamaz ve hatta ttf'den özel yazı tipleri kullanma imkanı olmadığından, html'nin spannable dönüştürücüye kendi uygulamasından başladıktan sonra buldum.


Aşağıdaki hatayı alıyorum: Hata: (80, 13) Çözülemedi: com.osbcp.cssparser: cssparser: 1.5 Bunu nasıl çözebilirim?
Araju

6

Bu sorunun eski olduğunu biliyorum. Burada diğer cevaplar Html.fromHtml()yöntemi önermektedir . Ben Kullanmak önermek HtmlCompat.fromHtml()gelen androidx.core.text.HtmlCompatpaketin. HtmlSınıfın geriye dönük uyumlu bir versiyonu olduğu için .

Basit kod:

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

Bu şekilde Android API sürüm kontrolünden kaçınabilirsiniz ve kullanımı kolaydır (tek satır çözüm).


Eski yöntemden farkı nedir? Html modunun amacı nedir?
user1209216

1
Böyle bir şey arıyordum. Teşekkürler :)
Subhrajyoti Sen

5

Basit kullanım Html.fromHtml("html string"). Bu çalışacak. Dize gibi etiketler <h1>varsa boşluklar gelecektir. Ancak bu alanları ortadan kaldıramayız. Yine de boşlukları kaldırmak istiyorsanız, dizedeki etiketleri kaldırabilir ve ardından dizeyi yönteme geçirebilirsiniz Html.fromHtml("html string");. Ayrıca genellikle bu dizeler sunucudan (dinamik) gelir, ancak sık sık değil, eğer dizeyi metoda olduğu gibi geçirmek daha iyi ise, etiketleri dizeden kaldırmaya çalışmaktan daha iyidir.


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

4

Gibi küresel bir yöntem yapın:

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

Ayrıca Faaliyet / Parçanızda aşağıdaki gibi kullanabilirsiniz:

text_view.setText(stripHtml(htmlText));

3

Bunu web görünümünü kullanarak uyguladım. Benim durumumda metin görünümünde metinle birlikte URL'den resim yüklemem gerekiyor ve bu benim için çalışıyor.

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'in düzgün görüntülenmesi için MIME türünü "text / html; charset = UTF-8" olarak ayarlamanız gerekir.
shawkinaw

3

Html framework sınıfının burada önerildiği gibi kullanılması çeşitli cevaplarla önerilmiştir, ancak ne yazık ki bu sınıf, 214637 , 14778 , 235128 ve 75953 sayılarında gösterildiği gibi Android'in farklı sürümlerinde ve çeşitli adressiz hatalarda farklı davranışlara sahiptir .

Bu nedenle, Html sınıfını, öğeler ve stil için daha fazla geri arama içeren Android sürümlerinde standartlaştırmak ve desteklemek için bir uyumluluk kitaplığı kullanmak isteyebilirsiniz:

Github projesi HtmlCompat

Çerçevenin Html sınıfına benzer olsa da, daha fazla geri aramaya izin vermek için bazı imza değişiklikleri gerekiyordu. GitHub sayfasından örnek:

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 Daha önce kapatılmış olan cevap, bir çerçeve yönteminin kullanımdan kaldırılmasıyla ilgili olarak bu sorunun cevabının bir kopyasıydı . Bir uyumluluk kütüphanesi kullanmanın daha iyi bir yaklaşım olmasını sağlamıştım. Her iki soruyu da açıkça farklı oldukları için birbirinin kopyası olarak işaretlemenin makul olduğunu düşünmüyorum.
Paul Lammertsma

2

Özel metin görünümü yazdığınızda, temel HTML seti metin özelliği bazı cihazlardan kaybolacaktır.

Bu yüzden aşağıdaki ek adımları yapmamız gerekir

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

yukarıdaki cevap güncellemesi


1

Çözümü elde etmek için aşağıdaki kodu kullanın:

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

Utitilty Yöntemi

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

Düzenlendi Kotlin uzantıları dönüştürmek için html den dize -

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

0

Biraz acayip ama yine de dahice bir çözüm önerebilir miyim! Bu makaleden fikri aldım ve Android için uyarladım. Temel olarak, kullanmak WebViewve düzenlemek istediğiniz HTML'yi düzenlenebilir bir div etiketine ekler ve kullanırsınız . Bu şekilde kullanıcı WebViewklavyeye dokunduğunda görünür ve düzenlemeye izin verir. Onlar sadece düzenlenmiş HTML ve voila geri almak için bazı JavaScript ekleyin!

İşte kod:

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

Ve işte bir Gist olarak bileşen.

Not: Orijinal çözümden yükseklik değişikliği geri aramasına ihtiyacım yoktu, bu yüzden burada eksik ama gerekirse kolayca ekleyebilirsiniz.


0

androidx.Projenizde * sınıfları kullanıyorsanız , kullanmalısınız HtmlCompat.fromHtml(text, flag). Yöntemin kaynağı:

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

Daha az kod, sadece bir satır ve onu kullanmanın önerilen yolu olduğundan Html.fromHtml'den daha iyi bir yoldur.


0

Bunun gibi basit Kotlin uzatma işlevini kullanabilirsiniz:

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

Ve kullanım:

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

0

Basitçe kullanın:

String variable="StackOverflow";
textView.setText(Html.fromHtml("<b>Hello : </b>"+ variable));
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.