Как отобразить HTML в TextView?


у меня просто HTML:

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

Я хочу, чтобы отображать HTML-форматированный текст в TextView. Как это сделать?

18 637

18 ответов:

вы должны использовать Html.fromHtml() для использования HTML в строках XML. Просто ссылка на строку с HTML в вашем макете XML не будет работать.

например (

myTextView.setText(Html.fromHtml("<h2>Title</h2><br><p>Description here</p>"));

например (>=Android Nougat):

myTextView.setText(Html.fromHtml("<h2>Title</h2><br><p>Description here</p>", Html.FROM_HTML_MODE_COMPACT));

чтобы различать версии Android используйте Build.VERSION.SDK_INT >= Build.VERSION_CODES.N.

взгляните на это:https://stackoverflow.com/a/8558249/450148

Это тоже очень хорошо!!

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

это работает только для нескольких тегов.

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

Если вы хотите иметь возможность настроить его через xml без каких-либо изменений в коде java вы можете найти эту идею полезной. Просто вы вызываете 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"/>

ниже код дал лучший результат для меня.

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

Если вы пытаетесь показать 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 для более подробной информации.

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

Если вы просто хотите отобразить текст html и на самом деле не нужен TextView, затем WebView и использовать его как следующие:

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

Это также не ограничивает вас несколькими тегами html.

стоит отметить, что метод Html.fromHtml (String source) устарело с уровня API 24. Если это ваш целевой API, вы должны использовать Html.fromHtml (String source, int flags) вместо.

лучший подход для использования разделов CData для строки в строках.xml-файл для получения фактического отображения содержимого 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 в строковом тексте сохраняет данные тега html нетронутыми даже после форматирования текста с помощью строки.метод форматирования. Итак, Html.fromHtml (str) отлично работает, и вы увидите полужирный текст в приветственном сообщении.

выход:

Добро пожаловать в ваш любимый магазин музыкальных приложений. Вошел в систему как: username

Я хотел бы также предложить следующий проект:https://github.com/NightWhistler/HtmlSpanner

использование почти такое же, как по умолчанию в Android конвертер:

(new HtmlSpanner()).fromHtml()

нашел его после того, как я уже начал собственную реализацию html в spannable converter, потому что стандартный Html.fromHtml не обеспечивает достаточной гибкости в управлении рендерингом и даже не позволяет использовать пользовательские шрифты из ttf

простой в использовании Html.fromHtml("html string"). Это сработает. Если строка имеет теги типа пробелы. Но мы не можем устранить эти пробелы. Если вы все еще хотите удалить пробелы, то вы можете удалить теги в строке, а затем передать строку в метод Html.fromHtml("html string"); . Также обычно эти строки поступают с сервера (динамического), но не часто, если это так, лучше передать строку, как она есть в метод, чем пытаться удалить теги из строки.

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

я реализовал это с помощью веб-просмотра. В моем случае я должен загрузить изображение из 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);

было предложено через различные ответы использовать Html класс framework, как предлагается здесь, но, к сожалению, этот класс имеет разное поведение в разных версиях Android и различные безадресные ошибки, как показано в выпусках 214637,14778,235128 и 75953.

поэтому вы можете использовать библиотеку совместимости для стандартизации и обратного переноса Html-класса через Android версии, которые включают в себя больше обратных вызовов для элементов и стилей:

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

всякий раз, когда вы пишете пользовательский текстовый вид основная функция HTML set text будет получить исчезли формы некоторых устройств.

поэтому нам нужно сделать следующие дополнительные шаги сделать это работа

открытый класс CustomTextView расширяет TextView {

//внутри конструктора

   setText(Html.fromHtml(getText().toString()));

}

создать глобальный метод, как:

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

могу ли я предложить несколько хаки, но все же гениальное решение! Я получил эту идею от в этой статье и адаптировал его для 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;
    }
}

и здесь - это компонент, как суть.

Примечание: мне не нужно изменение высоты обратного вызова из исходного решения, так что это отсутствует здесь, но вы можете легко добавить его при необходимости.