Как отобразить HTML в TextView?
У меня есть простой HTML:
<h2>Title</h2><br>
<p>description here</p>
Я хочу отобразить текст в стиле HTML это в TextView
, Как это сделать?
30 ответов
Вам нужно использовать Html.fromHtml()
использовать HTML в ваших XML-строках. Простая ссылка на строку с HTML в вашем макете XML не будет работать.
Вот что вы должны сделать:
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>"));
}
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));
}
Посмотрите на это: /questions/35689377/mozhet-podcherkivat-slova-v-tekste-textview/35689406#35689406
Это тоже очень хорошо!
<resource>
<string name="your_string">This is an <u>underline</u> text demo for TextView.</string>
</resources>
Это работает только для нескольких тегов.
Если вы хотите иметь возможность настроить его через 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"/>
Если вы пытаетесь отобразить 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));
Смотрите этот пост для получения дополнительной информации.
Я знаю, что этот вопрос старый. Другие ответы здесь предлагают Html.fromHtml()
метод. Я предлагаю вам использовать HtmlCompat.fromHtml()
от android.support.v4.text.HtmlCompat
пакет. Как это обратно совместимая версия Html
учебный класс.
Образец кода:
import android.support.v4.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, и она проста в использовании (однострочное решение).
Код ниже дал лучший результат для меня.
TextView myTextview = (TextView) findViewById(R.id.my_text_view);
htmltext = <your html (markup) character>;
Spanned sp = Html.fromHtml(htmltext);
myTextview.setText(sp);
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-тегами.
Наилучший подход к использованию разделов CData для строки в файле strings.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 без изменений даже после форматирования текста с использованием метода String.format. Итак, Html.fromHtml(str) работает нормально, и вы увидите жирный текст в приветственном сообщении.
Выход:
Добро пожаловать в ваш любимый музыкальный магазин приложений. Вы вошли как: имя пользователя
Созданы расширения Kotlin для конвертации html из String -
fun String?.toHtml(): Spanned? {
if (this.isNullOrEmpty()) return null
return HtmlCompat.fromHtml(this, HtmlCompat.FROM_HTML_MODE_COMPACT)
}
Стоит отметить, что метод Html.fromHtml(String source) устарел с 24 уровня API. Если это ваш целевой API, вам следует использовать Html.fromHtml(String source, int flags).
checkBoxTextView.text =
Html.fromHtml("<p><font color=#666666>I agree to</font><font color=#0173B7> <b><u>Terms & Conditions</u></b></font><font color=#666666> and the <u></font><b><font color=#0173B7>Privacy Policy</font></u></b></font></p>")
Я также хотел бы предложить следующий проект: https://github.com/NightWhistler/HtmlSpanner
Использование практически совпадает с конвертером Android по умолчанию:
(new HtmlSpanner()).fromHtml()
Нашел его после того, как я уже начал собственную реализацию конвертера html в spannable, потому что стандартный Html.fromHtml не обеспечивает достаточной гибкости управления рендерингом и даже не дает возможности использовать пользовательские шрифты из ttf.
В различных ответах было предложено использовать класс инфраструктуры Html, как предлагается здесь, но, к сожалению, этот класс ведет себя по-разному в разных версиях Android и в разных неполадках, как показано в выпусках 214637, 14778, 235128 и 75953.
Поэтому вы можете использовать библиотеку совместимости для стандартизации и переноса класса Html в версиях Android, который включает в себя больше обратных вызовов для элементов и стилей:
Хотя он похож на класс 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);
Если вы используете 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, так как кода меньше, только одна строка и рекомендуемый способ его использования.
Простое использование Html.fromHtml("html string")
, Это будет работать Если строка имеет такие теги, как <h1>
тогда пробелы придут. Но мы не можем устранить эти пробелы. Если вы все еще хотите удалить пробелы, вы можете удалить теги в строке, а затем передать строку в метод Html.fromHtml("html string");
, Также, как правило, эти строки поступают с сервера (динамического), но не часто, если лучше передать строку в метод, чем пытаться удалить теги из строки.
Я реализовал это с помощью веб-просмотра. В моем случае я должен загрузить изображение из 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);
Сделайте глобальный метод как:
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));
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
Люди предложили подкласс для TextView, WebView и всевозможных решений. Интересно, почему никто не упомянул простой адаптер привязки .
@BindingAdapter(value = ["htmlText"])
fun TextView.setHtmlText(string: String?) {
text = HtmlCompat.fromHtml(string?:"", HtmlCompat.FROM_HTML_MODE_COMPACT)
}
Итак, ваш TextView xml будет выглядеть как
<TextView
...
htmlText="<p>Your <b>HTML</b> text</p>"
... />
Simply use:
String variable="Stackru";
textView.setText(Html.fromHtml("<b>Hello : </b>"+ variable));
Всякий раз, когда вы пишете пользовательский текстовый вид, основные функции набора текста будут исчезать с некоторых устройств.
Таким образом, мы должны сделать следующие дополнительные шаги сделать это работа
открытый класс CustomTextView расширяет TextView {
// Внутри конструктора
setText(Html.fromHtml(getText().toString()));
}
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()));
}
}
}
обновление ответа выше
Используйте приведенный ниже код, чтобы получить решение:
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;
}
Вы можете использовать простую функцию расширения Kotlin следующим образом:
fun TextView.setHtmlText(source: String) {
this.text = HtmlCompat.fromHtml(source, HtmlCompat.FROM_HTML_MODE_LEGACY)
}
И использование:
textViewMessage.setHtmlText("Message: <b>Hello World</b>")
textview.text = HtmlCompat.fromHtml({htmlContent}, HtmlCompat.FROM_HTML_MODE_COMPACT)
Использование BindingAdapter:
@BindingAdapter("renderHtml")
fun bindRenderHtml(view: TextView, description: String?) {
if (description != null) {
view.text = HtmlCompat.fromHtml(description, FROM_HTML_MODE_COMPACT)
view.movementMethod = LinkMovementMethod.getInstance()
} else {
view.text = ""
}
}
Применение:
<TextView
android:id="@+id/content_text_view"
app:renderHtml="@{show.description}"
...
Могу я предложить какое-то хакерское, но все же гениальное решение! Я получил идею из этой статьи и адаптировал ее для 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;
}
}
А вот и компонент как суть.
Примечание. Мне не требовался обратный вызов для изменения высоты по сравнению с исходным решением, поэтому его здесь нет, но вы можете легко добавить его при необходимости.
Вы можете создать действительный HTML для Android, используя библиотека на Github: HtmlDsl
https://github.com/jaredrummler/HtmlDsl .
Библиотека предоставляет синтаксический сахар, чтобы сделать код более понятным и менее подверженным ошибкам, только за счет поддержки элементов и атрибутов, отображаемых Android.
Пример создания некоторого HTML:
textView.setHtml {
h3("Android Versions:")
ul {
li {
a(href = "https://developer.android.com/about/versions/12/get") {
+"Android 12 Beta"
}
}
li("Android 11")
li("Android 10")
li("Pie")
li("Oreo")
li("Nougat")
li("Marshmallow")
li("Lollipop")
// ...
}
small {
sub {
+"by "
a {
href = "https://github.com/jaredrummler"
text = "Jared Rummler"
}
}
}
}
Поддерживаемые элементы HTML для Android
TextView
:
<a href="...">
<b>
<big>
<blockquote>
<br>
<cite>
<dfn>
<div align="...">
<em>
<font color="..." face="...">
<h1>
<h2>
<h3>
<h4>
<h5>
<h6>
<i>
<img src="...">
<p>
<small>
<strike>
<strong>
<sub>
<sup>
<tt>
<u>
<ul>
<li>