У мене простий HTML :
<h2>Title</h2><br>
<p>description here</p>
Я хочу відобразити текст у стилі HTML TextView
. Як це зробити?
У мене простий HTML :
<h2>Title</h2><br>
<p>description here</p>
Я хочу відобразити текст у стилі HTML TextView
. Як це зробити?
Відповіді:
Вам потрібно скористатися 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>"));
}
h2
за визначенням створює навколо себе багато запасів. а p
також має деякий запас. якщо ви не хочете розриву, ви можете розглянути можливість використання інших html-елементів.
android.text.Html.fromHtml
. Я знаю, що більшість IDE виправлять це за вас, але для читабельності приємніше знати назви пакетів.
SetText (Html.fromHtml (bodyData)) є застарілим після апі 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));
}
Погляньте на це: https://stackoverflow.com/a/8558249/450148
Це дуже добре теж !!
<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));
Детальнішу інформацію див. У цій публікації .
Наведений нижче код дав найкращий результат для мене.
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
, тоді візьміть a WebView
та скористайтеся ним, як описано нижче:
String htmlText = ...;
webview.loadData(htmlText , "text/html; charset=UTF-8", null);
Це також не обмежує вас декількома тегами HTML.
layout_height="wrap_content"
. Натомість доведеться встановити явну висоту або match_parent.
Найкращий підхід до використання розділів 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) прекрасно працює, і ви побачите жирний текст у вітальному повідомленні.
Вихід:
Ласкаво просимо до вашого улюбленого магазину музичних програм. Увійшли як: ім’я користувача
Варто згадати, що метод Html.fromHtml (String source) є застарілим на рівні 24 API. Якщо це ваш цільовий API, слід використовувати Html.fromHtml (String source, int flags) .
Я також хочу запропонувати наступний проект: https://github.com/NightWhistler/HtmlSpanner
Використання майже таке ж, як і конвертер для Android за замовчуванням:
(new HtmlSpanner()).fromHtml()
Виявив це після того, як я вже запустив власну реалізацію html до перехідного перетворювача, тому що стандартний Html.fromHtml не забезпечує достатньої гнучкості в управлінні візуалізацією і навіть не має можливості використовувати спеціальні шрифти з ttf
Я знаю, це питання давнє. Інші відповіді тут пропонують 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);
Таким чином ви можете уникнути перевірки версії API Android, і це просто у використанні (однолінійне рішення).
Просте використання Html.fromHtml("html string")
. Це спрацює. Якщо в рядку є теги на зразок, <h1>
тоді прийдуть пробіли. Але ми не можемо усунути ці простори. Якщо ви все-таки хочете видалити пробіли, ви можете видалити теги в рядку, а потім передати рядок методу Html.fromHtml("html string");
. Загалом ці рядки надходять із сервера (динамічно), але не часто, якщо це краще, щоб передавати рядок як до методу, ніж намагатися видалити теги з рядка.
String value = html value ....
mTextView.setText(Html.fromHtml(value),TextView.BufferType.SPANNABLE)
Складіть глобальний метод на зразок:
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));
Я реалізував це за допомогою веб-перегляду. У моєму випадку мені потрібно завантажити зображення з 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, як запропоновано тут, але, на жаль, цей клас відрізняється поведінкою в різних версіях 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);
Щоразу, коли ви пишете спеціальний перегляд тексту, основна функція набору тексту HTML буде зникала з деяких пристроїв.
Тому нам потрібно зробити наступні додаткові кроки - це робота
public class CustomTextView extends TextView {
public CustomTextView(..) {
// other instructions
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>"))
Метод утітліті
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;
}
Можна запропонувати дещо хитре, але все ж геніальне рішення! Я отримав ідею з цієї статті та адаптував її для Android. В основному ви використовуєте a 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;
}
}
І ось компонент як Гіст.
Примітка: мені не знадобився зворотний виклик зміни висоти від оригінального рішення, тому його тут немає, але ви можете легко додати його, якщо потрібно.
Якщо ви використовуєте 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, оскільки код менше, лише один рядок, і рекомендований спосіб його використання.
Ви можете використовувати просту функцію розширення Kotlin таким:
fun TextView.setHtmlText(source: String) {
this.text = HtmlCompat.fromHtml(source, HtmlCompat.FROM_HTML_MODE_LEGACY)
}
І використання:
textViewMessage.setHtmlText("Message: <b>Hello World</b>")
Просто використовуйте:
String variable="StackOverflow";
textView.setText(Html.fromHtml("<b>Hello : </b>"+ variable));