Android N已弃用Html.fromHtml

我正在使用Html.fromHtml来查看TextView中的html。

Spanned result = Html.fromHtml(mNews.getTitle());
...
...
mNewsTitle.setText(result);

但是Html.fromHtml现在在Android N+中已弃用

我怎样才能找到做这件事的新方法?

203671 次浏览

来自官方文件:

fromHtml(String)方法在API级别24中已弃用。使用fromHtml(String, int) 相反。< / p >

  1. TO_HTML_PARAGRAPH_LINES_CONSECUTIVE toHtml(Spanned, int)选项:将由'\n'分隔的连续文本行包装在<p>内 李元素。< / p > < / >

  2. TO_HTML_PARAGRAPH_LINES_INDIVIDUAL toHtml(Spanned, int)选项:将由'\n'分隔的每行文本包装在<p><li>中 李元素。< / p > < / >

https://developer.android.com/reference/android/text/Html.html

< p > 更新: 下面提到的@Andy谷歌已经创建了HtmlCompat,它可以用来代替下面的方法。添加这个依赖implementation 'androidx.core:core:1.0.1 建造。

. gradle文件。确保你使用的是androidx.core:core的最新版本

这允许你使用:

HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY);

你可以阅读更多关于HtmlCompat-documentation上不同标志的信息

< >强最初的回答: 在Android N中,他们引入了一个新的Html.fromHtml方法。Html.fromHtml现在需要一个额外的参数,名为flags。这个标志让您可以更好地控制HTML的显示方式。< / p >

在Android N及以上版本,你应该使用这个新方法。旧的方法已被弃用,并可能在未来的Android版本中被删除。

你可以创建自己的util方法,在旧版本上使用旧方法,在Android N及以上版本上使用新方法。如果你不添加版本检查,你的应用就会在较低的Android版本上崩溃。您可以在Util类中使用此方法。

@SuppressWarnings("deprecation")
public static Spanned fromHtml(String html){
if(html == null){
// return an empty spannable if the html is null
return new SpannableString("");
}else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// FROM_HTML_MODE_LEGACY is the behaviour that was used for versions below android N
// we are using this flag to give a consistent behaviour
return Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY);
} else {
return Html.fromHtml(html);
}
}

如果需要,可以将HTML.FROM_HTML_MODE_LEGACY转换为附加参数。这使您可以更好地控制使用哪个标志。

你可以阅读更多关于不同的标志在 Html类文档 < / p >

我有很多这些警告,我总是使用FROM_HTML_MODE_LEGACY,所以我做了一个名为HtmlCompat的助手类,包含以下内容:

   @SuppressWarnings("deprecation")
public static Spanned fromHtml(String source) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return Html.fromHtml(source, Html.FROM_HTML_MODE_LEGACY);
} else {
return Html.fromHtml(source);
}
}

比较fromHtml()的标志。

<p style="color: blue;">This is a paragraph with a style</p>


<h4>Heading H4</h4>


<ul>
<li style="color: yellow;">
<font color=\'#FF8000\'>li orange element</font>
</li>
<li>li #2 element</li>
</ul>


<blockquote>This is a blockquote</blockquote>


Text after blockquote
Text before div


<div>This is a div</div>


Text after div

FROM_HTML FLAGS

fromHtml

这个方法是API级别24中的< >强弃用< / >强

你应该使用FROM_HTML_MODE_LEGACY

用空行(两个换行符)分隔块级元素 人物)介于两者之间。这是n之前的遗留行为

代码

if (Build.VERSION.SDK_INT >= 24)
{
etOBJ.setText(Html.fromHtml("Intellij \n Amiyo",Html.FROM_HTML_MODE_LEGACY));


}
else
{
etOBJ.setText(Html.fromHtml("Intellij \n Amiyo"));
}

在芬兰湾的科特林

fun setTextHTML(html: String): Spanned
{
val result: Spanned = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY)
} else {
Html.fromHtml(html)
}
return result
}

调用

 txt_OBJ.text  = setTextHTML("IIT Amiyo")

你可以使用

//noinspection deprecation
return Html.fromHtml(source);

仅对单个语句而不是整个方法抑制检查。

为了扩展@Rockney和@k2col的答案,改进后的代码可以如下所示:

@NonNull
public static Spanned fromHtml(@NonNull String html) {
if (CompatUtils.isApiNonLowerThan(VERSION_CODES.N)) {
return Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY);
} else {
//noinspection deprecation
return Html.fromHtml(html);
}
}

其中CompatUtils.isApiNonLowerThan:

public static boolean isApiNonLowerThan(int versionCode) {
return Build.VERSION.SDK_INT >= versionCode;
}

不同之处在于没有额外的局部变量,并且弃用只在else分支中。所以这不会抑制所有的方法,而是单个分支。

它可以帮助谷歌将决定在一些未来的Android版本中弃用甚至fromHtml(String source, int flags)方法。

框架类已被修改为需要一个标志来通知fromHtml()如何处理换行符。这是在Nougat中添加的,并且只涉及到这个类在Android版本之间不兼容的挑战。

我已经发布了一个兼容性库来标准化和后移植类,并包括更多元素和样式的回调:

https://github.com/Pixplicity/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标签,包括ul ol li标签。 创建一个标签处理程序,如下所示

import org.xml.sax.XMLReader;


import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.Html;
import android.text.Html.TagHandler;
import android.util.Log;


public class MyTagHandler implements TagHandler {
boolean first= true;
String parent=null;
int index=1;
@Override
public void handleTag(boolean opening, String tag, Editable output,
XMLReader xmlReader) {


if(tag.equals("ul")) parent="ul";
else if(tag.equals("ol")) parent="ol";
if(tag.equals("li")){
if(parent.equals("ul")){
if(first){
output.append("\n\t•");
first= false;
}else{
first = true;
}
}
else{
if(first){
output.append("\n\t"+index+". ");
first= false;
index++;
}else{
first = true;
}
}
}
}
}

将文本设置为Activity,如下所示

@SuppressWarnings("deprecation")
public void init(){
try {
TextView help = (TextView) findViewById(R.id.help);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
help.setText(Html.fromHtml(getString(R.string.help_html),Html.FROM_HTML_MODE_LEGACY, null, new MyTagHandler()));
} else {
help.setText(Html.fromHtml(getString(R.string.help_html), null, new MyTagHandler()));
}
} catch (Exception e) {
e.printStackTrace();
}


}

和html文本资源字符串文件作为

& lt; ![CDATA[…原始HTML数据…]]比;

如果你有幸在Kotlin上开发, 只需创建一个扩展函数:

fun String.toSpanned(): Spanned {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
return Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)
} else {
@Suppress("DEPRECATION")
return Html.fromHtml(this)
}
}

而且用在任何地方都很贴心:

yourTextView.text = anyString.toSpanned()

或者你可以使用androidx.core.text.HtmlCompat:

HtmlCompat.fromHtml("<b>HTML</b>", HtmlCompat.FROM_HTML_MODE_LEGACY)

HtmlCompat docs

如果你正在使用芬兰湾的科特林,我通过使用Kotlin扩展来实现这一点:

fun TextView.htmlText(text: String){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
setText(Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY))
} else {
setText(Html.fromHtml(text))
}
}

然后像这样称呼它:

textView.htmlText(yourHtmlText)

这是我的解决方案。

 if (Build.VERSION.SDK_INT >= 24) {
holder.notificationTitle.setText(Html.fromHtml(notificationSucces.getMessage(), Html.FROM_HTML_MODE_LEGACY));
} else {
holder.notificationTitle.setText(Html.fromHtml(notificationSucces.getMessage()));


}

只需要创建一个函数:

public Spanned fromHtml(String str){
return Build.VERSION.SDK_INT >= 24 ? Html.fromHtml(str, Html.FROM_HTML_MODE_LEGACY) : Html.fromHtml(str);
}

对于Kotlin用户,我们可以使用String.parseAsHtml()扩展函数,该函数使用HtmlCompat,从而进行兼容性检查。

这可以从android核心kotlin扩展androidx.core:core-ktx中获得