如何在TextView中显示HTML?
-
22-09-2019 - |
题
我有简单的 超文本标记语言:
<h2>Title</h2><br>
<p>description here</p>
我想在其中显示 HTML 样式的文本 TextView
. 。这个怎么做?
解决方案
您需要使用 Html.fromHtml()
在XML字符串使用HTML。只需在您的布局XML引用一个字符串与HTML将无法工作。
这是你应该做的:
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));
}
对此看看: 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代码中任何修改您可能会发现这种想法有助于配置。简单地调用构造函数从初始化和设置文本为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);
如果你正试图从一个字符串资源ID显示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());
如果你只是想显示一些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部分保持,甚至使用的String.format方法格式化文本后保持完整的HTML标签数据。所以,Html.fromHtml(STR)工作正常,你会看到在欢迎辞中的粗体文字。
<强>输出:强>
欢迎,您喜爱的音乐应用程序商店。在记录为:用户名
值得一提的是,方法的Html 是弃用API级别24.如果这是你的目标API的.fromHtml(字符串源),你应该使用的 Html.fromHtml(字符串源,INT标志)代替。
我还想提出以下项目: https://github.com/NightWhistler/HtmlSpanner
用法是几乎相同默认机器人转换器:
(new HtmlSpanner()).fromHtml()
发现它后,我已经被自己的HTML实现到spannable转换器开始,因为标准Html.fromHtml不超过渲染来自TTF
控制,甚至不可能使用自定义字体提供足够的灵活性简单使用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);
通过各种答案建议使用 网页 此处建议使用框架类,但不幸的是,该类在不同版本的 Android 中具有不同的行为以及各种未解决的错误,如问题中所示 214637, 14778, 235128 和 75953.
因此,您可能希望使用兼容性库来跨 Android 版本标准化和反向移植 Html 类,其中包括更多元素和样式的回调:
虽然它与框架的 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.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);
通过这种方式,您可以避开Android的API版本检查,并可以很容易地使用(单线解决方案)。
当你编写自定义文本视图基本的HTML文本集功能将得到消失形式的一些设备。
所以,我们需要做以下步骤addtional提出的是工作
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()));
}
}
}
的更新 五月我建议一个有点哈克但还是天才的解决方案!我从这篇文章的想法,并适应它为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;
}
}
和此处是组件作为要点。
请注意:我并不需要从原来的解决方案的高度变化的回调,这样的缺失在这里,但如果需要的话,你可以轻松地添加它
。如果您在项目中使用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更好的方式,和使用它推荐的方式。