Html.fromHtml 在 Android 中弃用
Html.fromHtml deprecated in Android N
我正在使用 Html.fromHtml
在 TextView
中查看 html。
Spanned result = Html.fromHtml(mNews.getTitle());
...
...
mNewsTitle.setText(result);
但 Html.fromHtml
现在已在 Android N+
中弃用
What/How 我找到了新的方法吗?
来自官方文档:
fromHtml(String)
method was deprecated in API level 24. use fromHtml(String, int)
instead.
TO_HTML_PARAGRAPH_LINES_CONSECUTIVE
Option for toHtml(Spanned, int)
: Wrap consecutive lines of text delimited by '\n'
inside <p>
elements.
TO_HTML_PARAGRAPH_LINES_INDIVIDUAL
Option for toHtml(Spanned, int)
: Wrap each line of text delimited by '\n'
inside a <p>
or a <li>
element.
https://developer.android.com/reference/android/text/Html.html
更新:
因为 Google 已经创建了 HtmlCompat
可以用来代替下面的方法。添加此依赖项 implementation 'androidx.core:core:1.0.1
到您应用的 build.gradle 文件。确保使用最新版本的 androidx.core:core
.
这允许您使用:
HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY);
上阅读更多关于不同标志的信息
原答案:
在 Android N 他们引入了一种新的 Html.fromHtml
方法。 Html.fromHtml
现在需要一个名为 flags 的附加参数。此标志使您可以更好地控制 HTML 的显示方式。
在 Android N 及以上你应该使用这个新方法。旧方法已弃用,可能会在未来的 Android 版本中删除。
您可以创建自己的 Util 方法,它将在旧版本上使用旧方法,在 Android N 及更高版本上使用新方法。如果您不添加版本检查,您的应用程序将在较低的 Android 版本上中断。您可以在 Util class 中使用此方法。
@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
转换为附加参数。这使您可以更好地控制使用哪个标志。
我有很多这样的警告并且我总是使用 FROM_HTML_MODE_LEGACY 所以我制作了一个名为 HtmlCompat 的助手 class 包含以下内容:
@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
This method was deprecated in API level 24.
Separate block-level elements with blank lines (two newline
characters) in between. This is the legacy behavior prior to 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"));
}
对于 Kotlin
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
分支中弃用。所以这不会抑制所有方法,而是单个分支。
当 Google 决定在 Android 的某些未来版本中甚至弃用 fromHtml(String source, int flags)
方法时,它会有所帮助。
框架 class 已修改为需要一个标志来通知 fromHtml()
如何处理换行符。这是在 Nougat 中添加的,仅涉及 class 跨 Android.
版本不兼容的挑战
我发布了一个兼容性库来标准化和向后移植 class 并包含更多元素和样式回调:
虽然它类似于框架的 Html class,但需要更改一些签名以允许更多回调。这是来自 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 资源字符串文件上的文本为
如果你有幸在 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)
如果您使用的是 Kotlin,我通过使用 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);
}
我正在使用 Html.fromHtml
在 TextView
中查看 html。
Spanned result = Html.fromHtml(mNews.getTitle());
...
...
mNewsTitle.setText(result);
但 Html.fromHtml
现在已在 Android N+
What/How 我找到了新的方法吗?
来自官方文档:
fromHtml(String)
method was deprecated in API level 24. usefromHtml(String, int)
instead.
TO_HTML_PARAGRAPH_LINES_CONSECUTIVE
Option fortoHtml(Spanned, int)
: Wrap consecutive lines of text delimited by'\n'
inside<p>
elements.
TO_HTML_PARAGRAPH_LINES_INDIVIDUAL
Option fortoHtml(Spanned, int)
: Wrap each line of text delimited by'\n'
inside a<p>
or a<li>
element.
https://developer.android.com/reference/android/text/Html.html
更新:
因为 HtmlCompat
可以用来代替下面的方法。添加此依赖项 implementation 'androidx.core:core:1.0.1
到您应用的 build.gradle 文件。确保使用最新版本的 androidx.core:core
.
这允许您使用:
HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY);
上阅读更多关于不同标志的信息
原答案:
在 Android N 他们引入了一种新的 Html.fromHtml
方法。 Html.fromHtml
现在需要一个名为 flags 的附加参数。此标志使您可以更好地控制 HTML 的显示方式。
在 Android N 及以上你应该使用这个新方法。旧方法已弃用,可能会在未来的 Android 版本中删除。
您可以创建自己的 Util 方法,它将在旧版本上使用旧方法,在 Android N 及更高版本上使用新方法。如果您不添加版本检查,您的应用程序将在较低的 Android 版本上中断。您可以在 Util class 中使用此方法。
@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
转换为附加参数。这使您可以更好地控制使用哪个标志。
我有很多这样的警告并且我总是使用 FROM_HTML_MODE_LEGACY 所以我制作了一个名为 HtmlCompat 的助手 class 包含以下内容:
@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
This method was
deprecatedin API level 24.
Separate block-level elements with blank lines (two newline characters) in between. This is the legacy behavior prior to 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"));
}
对于 Kotlin
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
分支中弃用。所以这不会抑制所有方法,而是单个分支。
当 Google 决定在 Android 的某些未来版本中甚至弃用 fromHtml(String source, int flags)
方法时,它会有所帮助。
框架 class 已修改为需要一个标志来通知 fromHtml()
如何处理换行符。这是在 Nougat 中添加的,仅涉及 class 跨 Android.
我发布了一个兼容性库来标准化和向后移植 class 并包含更多元素和样式回调:
虽然它类似于框架的 Html class,但需要更改一些签名以允许更多回调。这是来自 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 资源字符串文件上的文本为
如果你有幸在 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)
如果您使用的是 Kotlin,我通过使用 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);
}