在Android N

时间:2016-06-19 07:00:13

标签: android deprecated android-7.0-nougat

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

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

但{N}

现已弃用Html.fromHtml

什么/如何找到新方法?

14 个答案:

答案 0 :(得分:493)

<强>更新: 正如@Andy提到谷歌创建的HtmlCompat可以用来代替下面的方法。添加此依赖项implementation 'androidx.core:core:1.0.1  到你的应用程序的build.gradle文件。请务必使用最新版本的androidx.core:core

这允许您使用:

HtmlCompat.fromHtml(HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY);

您可以阅读HtmlCompat-documentation

上有关不同标志的更多信息

原始回答: 在Android N中,他们引入了一种新的Html.fromHtml方法。 Html.fromHtml现在需要一个名为flags的附加参数。此标志使您可以更好地控制HTML的显示方式。

在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 class documentation

答案 1 :(得分:87)

我有很多这些警告,而且我总是使用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);
        }
    }

答案 2 :(得分:49)

比较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

答案 3 :(得分:25)

或者您可以使用androidx.core.text.HtmlCompat

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

HtmlCompat docs

答案 4 :(得分:24)

如果你有幸在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()

答案 5 :(得分:13)

<强> fromHtml

  

此方法在 API级别24 已弃用

您应该使用 FROM_HTML_MODE_LEGACY

  

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

<强>代码

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
    }

对于Kotlin

 txt_OBJ.text  = setTextHTML("IIT Amiyo")

呼叫

query = Account.query(Account.userid >= 40, Account.userid < 50)

答案 6 :(得分:8)

来自官方文件:

  在API级别24中弃用了

fromHtml(String)方法。使用fromHtml(String, int)   代替。

     
      
  1. TO_HTML_PARAGRAPH_LINES_CONSECUTIVE toHtml(Spanned, int)的选项:在'\n'内包裹由<p>分隔的连续文字行   元件。

  2.   
  3. TO_HTML_PARAGRAPH_LINES_INDIVIDUAL toHtml(Spanned, int)选项:在'\n'<p>内包裹由<li>分隔的每一行文字   元件。

  4.   

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

答案 7 :(得分:5)

为了扩展@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)方法,那么它会有所帮助。

答案 8 :(得分:4)

您可以使用

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

仅针对单个陈述而不是整个方法来抑制检查。

答案 9 :(得分:4)

如果您使用的是 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)

答案 10 :(得分:2)

框架类已被修改为需要一个标志来通知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);

答案 11 :(得分:1)

这是我的解决方案。

 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()));

    }

答案 12 :(得分:0)

只需执行一个功能:

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

答案 13 :(得分:-1)

请尝试以下操作以支持基本的html标记,包括ul ol li标记。 创建一个Tag处理程序,如下所示

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数据...]]&gt;