DataBinding中的Html.fromHtml - 安卓

13

我在我的项目中使用dataBinding,当我拥有以下的xml时它可以正常工作:

Translated Text:

我在我的项目中使用dataBinding,当我拥有以下的xml时它可以正常工作:

    <TextView
        android:id="@+id/txtDateCreate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{String.format(@string/DateCreate,others.created)}" />
但是当我改成以下代码后,程序崩溃了:
    <TextView
        android:id="@+id/txtDateCreate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{Html.fromHtml(String.format(@string/DateCreate,others.created))}" />

在我的string.xml文件中:

<resources>
<string name="DateCreate">open : <![CDATA[<b><font color=#FF0000>%s</b>]]></string>
</resources>
3个回答

22

您需要先在XML中导入HTML。

<data>
    <import type="android.text.Html"/>
</data>

<TextView
    android:id="@+id/txtDateCreate"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{Html.fromHtml(String.format(@string/DateCreate,others.created))}" />

我正在尝试实现您的解决方案,但我获取的文本来自API调用,因此在屏幕的第一次初始化时,该字符串为空,应用程序会崩溃。我该如何实现它以解决这个问题? - Mahmoud Omara
请查看此链接:https://dev59.com/q1wZ5IYBdhLWcg3wJ9jN#72457240 - Adarsh Vijayan P

7

我认为视图不应具有任何逻辑/转换来显示数据。 我建议为此创建一个BindingAdapter:

@BindingAdapter({"android:htmlText"})
public static void setHtmlTextValue(TextView textView, String htmlText) {
    if (htmlText == null)
        return;

    Spanned result;
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
        result = Html.fromHtml(htmlText, Html.FROM_HTML_MODE_LEGACY);
    } else {
        result = Html.fromHtml(htmlText);
    }
    textView.setText(result);
}

然后在布局中像往常一样调用它:

<TextView
                android:id="@+id/bid_footer"
                style="@style/MyApp.TextView.Footer"
                android:htmlText="@{viewModel.bidFooter} />

viewModel.bidFooter中,包含获取字符串/跨度/字符文本的逻辑,考虑到没有直接依赖于上下文、活动等。


如果您想直接使用字符串资源ID,而不是使用ViewModel,该怎么办? - l33t
这就像是将所有逻辑放在您的activity/fragment或util/ktx类中...然后在获取数据值后,在布局中定义一个数据绑定变量,并从activity/fragment中设置该值。 - Carlos Daniel

1
下面这行代码在Android N(API级别24)中已被弃用。
Html.fromHtml(content)

现在你需要提供两个参数(content 和 flag),如下所示:
Html.fromHtml(content, HtmlCompat.FROM_HTML_MODE_LEGACY)

所以我建议您像下面这样使用@BindingAdapter

object BindingUtils {

@JvmStatic
@BindingAdapter("loadHtml")
fun loadHtml(textView: TextView, content: String?){
    if (!content.isNullOrEmpty()) {
        textView.text = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            Html.fromHtml(content, HtmlCompat.FROM_HTML_MODE_LEGACY)
        } else {
            Html.fromHtml(content)
        }
    }
}

}

在你的 XML 文件中:
 <data>
    <import type="com.example.utils.BindingUtils"/>
</data>
<TextView
        android:id="@+id/textView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:loadHtml="@{String.format(@string/DateCreate,others.created))}"/>

有帮助的答案!需要注意以下几点:1)可以使用HtmlCompat.fromHtml(content, HtmlCompat.FROM_HTML_MODE_LEGACY)来避免检查SDK版本的需要。2)对于string.xml资源,需要转义Html标签或它们的开放括号'<',以防止Android系统自动删除它们。3)上面的最后一句话包含一个额外的闭合括号')'。 - Cherif Diallo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接