У меня есть простой 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-элементов.
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));
}
Посмотрите на это: https://stackoverflow.com/questions/8558218/can-underline-words-in-textview-text
Это тоже хорошо!
<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"/>
Следующий код дал лучший результат для меня.
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));
Подробнее см. .
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());
Лучший подход к использованию разделов 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) устарел с уровня API 24. Если этот целевой API, вы вместо этого следует использовать Html.fromHtml(String source, int flags).
Если вы просто хотите отобразить некоторый HTML-текст и не нуждаетесь в TextView
, тогда возьмите WebView
и используйте его, как показано ниже:
String htmlText = ...;
webview.loadData(htmlText , "text/html; charset=UTF-8", null);
Это также не ограничивает вас несколькими тегами html.
layout_height="wrap_content"
. Вы должны будете установить явную высоту или match_parent вместо этого.
Я также хотел бы предложить следующий проект: https://github.com/NightWhistler/HtmlSpanner
Использование почти такое же, как и для Android-конвертера по умолчанию:
(new HtmlSpanner()).fromHtml()
Нашел его после того, как я уже начал свою собственную реализацию html в spannable converter, потому что стандартный Html.fromHtml не обеспечивает достаточной гибкости при управлении рендерингом и даже не позволяет использовать пользовательские шрифты из ttf
Простое использование Html.fromHtml("html string")
. Это сработает. Если строка имеет теги типа <h1>
, тогда появятся пробелы. Но мы не можем устранить эти пространства. Если вы все же хотите удалить пробелы, вы можете удалить теги в строке, а затем передать строку методу 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);
Сделайте глобальный метод, например:
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));
Всякий раз, когда вы пишете пользовательский текстовый вид, основные функции набора текста будут исчезать с некоторых устройств.
Таким образом, мы должны сделать следующие дополнительные шаги сделать это работа
public class CustomTextView extends TextView {
public CustomTextView(..) {
// other instructions
setText(Html.fromHtml(getText().toString()));
}
}
Было предложено с помощью различных ответов использовать Html класс среды как предложено здесь, но, к сожалению, этот класс имеет различное поведение в разных версиях Android и различных безадресных ошибок, как показано в вопросах 214637, 14778, 235128 и 75953.
Поэтому вы можете использовать библиотеку совместимости для стандартизации и резервного копирования класса Html в версиях Android, который включает в себя больше обратных вызовов для элементов и стилей:
Хотя он похож на класс Html framework, для обеспечения большего количества обратных вызовов потребовались некоторые изменения подписи. Здесь образец с страницы 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);
Могу ли я предложить несколько хакерское, но все еще гениальное решение! Я получил эту идею из этой статьи и адаптировал ее для 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 read without editing the text before
mJsObject.text = text;
}
public String getText() {
return mJsObject.text;
}
}
И вот компонент как Gist.
Примечание. Мне не нужен обратный вызов изменения высоты из исходного решения, так что здесь отсутствует, но вы можете легко добавить его, если необходимо.