11

我想将我的文本的某些部分设置为粗体,其值是使用 DataBinding 和 ViewModel 设置的。

例如

如果您被选中,您将为您的配对支付160 美元。

我正在使用字符串资源

<string name="product_price">If you are selected, you will have to pay $%d for your pair.</string>

<TextView
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_marginEnd="@dimen/spacing_xlarge"
          android:layout_marginStart="@dimen/spacing_xlarge"
          android:layout_marginBottom="@dimen/spacing_small"
          android:text="@{@string/product_price(productPrice)}"
          android:textColor="@color/button_tertiary"
          android:visibility="@{productPrice > 0}"
          style="@style/Body.Small"
          />

目前通过设置使用带有绑定的 ViewModel 传递产品价格binding.setProductPrice(Object.getPrice())

我知道以下解决方案:但想尝试使用 DataBinding

  • 使用 Html 文本 - 但不想在代码中使用它。
  • 在水平样式中使用不同的 TextView。将该产品价格的样式设置为粗体。- 非常糟糕的做法
  • 使用 SpannableString - 但不想在代码中使用它。

但上述所有解决方案都是解决方法。

问题 ::

Want to try DataBinding feature which can be used to style certain part of string. Just like SpannableString

Manipulate String in the Layout file using DataBinding

4

6 回答 6

6

根据@CommonsWare,

通过添加基本 Html 标签尝试<string name="product_price">If you are selected, you will have to pay <![CDATA[<b>$%d</b>]]> for your pair.</string>

布局文件:导入的 Html

 <?xml version="1.0" encoding="utf-8"?>
 <layout
   <data>
   <import type="android.text.Html"/>
   <data>
     <LinearLayout>
       <android.support.design.widget.CoordinatorLayout>
       <TextView
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_marginEnd="@dimen/spacing_xlarge"
          android:layout_marginStart="@dimen/spacing_xlarge"
          android:layout_marginBottom="@dimen/spacing_small"
          android:text="@{Html.fromHtml(@string/product_price(productPrice))}"
          android:textColor="@color/button_tertiary"
          android:visibility="@{productPrice > 0}"
          style="@style/Body.Small"
          />
       </android.support.design.widget.CoordinatorLayout>
     </LinearLayout>
 </layout>
于 2018-08-13T13:49:20.303 回答
5

您必须创建一个BindingAdapterSpannableStringBuilder

绑定适配器

object Util {
    @BindingAdapter("main","secondText")
        @JvmStatic
        fun setBoldString(view: AppCompatTextView, maintext: String,sequence: String) {
            view.text = Util.getBoldText(maintext, sequence)
        }



    @JvmStatic
        fun getBoldText(text: String, name: String): SpannableStringBuilder {
            val str = SpannableStringBuilder(text)
            val textPosition = text.indexOf(name)
            str.setSpan(android.text.style.StyleSpan(Typeface.BOLD),
                    textPosition, textPosition + name.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            return str
        }
}

XML

    <android.support.v7.widget.AppCompatTextView
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:main="@{`you will pay $160 for your pair`}"
        app:secondText="@{`$160`}"
        android:textColor="@color/black"
        android:textSize="22sp" />

可能对你有帮助。

于 2018-08-13T13:54:20.957 回答
3

您可以将绑定适配器与 SpannableString 结合使用。一旦定义了绑定适配器,就可以在所有布局文件中重用它。

@BindingAdapter({"mainText", "priceToFormat"})
public static void format(TextView textView, String mainText, float 
      productPrice){
   //Use spannable string to format your text accordingly
   textView.setText(formattedText);
}

您可以像这样在布局文件中传递这些参数:

<TextView
   .
   .
   app:mainText = "@{ priceText }"
   app:priceToFormat = "@{ price }"/>

祝你好运。

于 2018-08-13T12:53:54.633 回答
0

如下所述使用 BindingAdapter

    @BindingAdapter("setBold")
    @JvmStatic
    public static void setBold(TextView view, boolean isBold) {
        if (isBold) {
            view.setTypeface(null, Typeface.BOLD);
        } else {
            view.setTypeface(null, Typeface.NORMAL);
        }
    }

并在 xml 中使用它,如下所示:

  <androidx.appcompat.widget.AppCompatTextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:text="@{model.value}"
        app:setBold="@{model.isBold}"
   />
于 2020-05-31T15:49:55.837 回答
0

由于 Html.fromHtml 签名在 API 级别 24 (Android N) 发生了变化,Android 团队引入了 HtmlCompat 以在任何 api 级别使用相同的签名。

因此,您应该使用 HtmlCompat 类:

HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY);

要使用它,您可以在项目的 build.gradle 中包含 AndroidX 核心:

implementation 'androidx.core:core:1.3.1'

布局 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
 <layout
   <data>
   <import type="androidx.core.text.HtmlCompat"/>
   <data>
     <LinearLayout>
       <android.support.design.widget.CoordinatorLayout>
       <TextView
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_marginEnd="@dimen/spacing_xlarge"
          android:layout_marginStart="@dimen/spacing_xlarge"
          android:layout_marginBottom="@dimen/spacing_small"
          android:text="@{HtmlCompat.fromHtml(@string/product_price(productPrice),HtmlCompat.FROM_HTML_MODE_LEGACY)}"
          android:textColor="@color/button_tertiary"
          android:visibility="@{productPrice > 0}"
          style="@style/Body.Small"
          />
       </android.support.design.widget.CoordinatorLayout>
     </LinearLayout>
 </layout>
于 2020-10-09T18:47:17.517 回答
-2

// 将此方法放在您的模型类中,其中名称是字符串变量,根据给定的 api 响应设置

public Spanned getHtmlText(){
        return Html.fromHtml("<b>" + name + "</b>");
    }

// 在 xml 中使用 this 其中 userList 是模型类的变量名。

 android:text="@{userList.htmlText}"
于 2018-08-13T13:28:24.747 回答