使用 Spannable 类型的 ObservableField 进行数据绑定

Data binding using ObservableField of type Spannable

我一直在我的 ViewModel 中使用 ObservableField()。但是现在我想要显示 HTML 格式的文本。我可以为此使用 Spannable 类型的 ObservableField 吗?在旧情况下,我使用 "setEditText" 方法,这很有效。

新情况:

    var spannableText = ObservableField<Spannable>()
    fun setEditTextUsingObservable() {
        var complete = "<ul><li><a href='https://www.someurl.nl/hello/'>Click here!</a></li></ul>"
        this.spannableText.set(complete.toSpannable())
    }

旧情况:

    fun setEditText(textView: TextView, text: String) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            textView.text = Html.fromHtml(text, Html.TO_HTML_PARAGRAPH_LINES_CONSECUTIVE).toSpannable()
        } else {
            @Suppress("DEPRECATION")
            textView.text = Html.fromHtml(text).toSpannable()
        }
        textView.movementMethod = LinkMovementMethod.getInstance()
    }

相关XML:

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">

        <data>
            <variable
                name="viewModel"
                type="MyViewModel" />
        </data>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

                    <TextView
                        android:id="@+id/spannableText"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@{viewModel.spannableText}"/>
        </LinearLayout>
    </layout>

解决方案是使用 bindadapter ViewModel

 val spannable: ObservableField<Spanned> =ObservableField(Html
.fromHtml("<ul><li><a href='https://www.someurl.nl/hello/'>Click here!</a></li></ul>"))


fun changeText(text: String) {
    spannable.set(Html.fromHtml(text))
    }
    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">

        <data>
            <variable
                name="viewModel"
                type="MyViewModel" />
        </data>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

                    <TextView
                        android:id="@+id/spannableText"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@{viewModel.spannable}"/>
        </LinearLayout>
    </layout>

绑定适配器

@BindingAdapter("android:text")
public static void Spanned(TextView textView, Spanned spannable) {
    textView.setText(spannable);
}

现在您可以使用 changeText 功能来更改它。

正确的解决方案是使用 SpannableString 而不是 Spannable。

var spannableText = ObservableField<SpannableString>()

    val text: SpannableString?
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        text = SpannableString(Html.fromHtml(complete, Html.TO_HTML_PARAGRAPH_LINES_CONSECUTIVE))
    } else {
        @Suppress("DEPRECATION")
        text = SpannableString(Html.fromHtml(complete))
    }

    spannableText.set(text)