Android 使用数据绑定将文本的某些部分设置为粗体

Android 使用数据绑定将文本的某些部分设置为粗体,android,android-databinding,android-mvvm,Android,Android Databinding,Android Mvvm,我想将文本的某些部分设置为粗体,其值是使用ViewModel的数据绑定设置的 例如 如果您被选中,您将为您的一双鞋支付160美元 我正在使用字符串资源 如果您被选中,您必须为您的配对支付$%d。 当前通过设置Binding.setProductPrice(Object.getPrice()) 我知道以下解决方案:但我想尝试使用数据绑定 使用Html文本-但不想在代码中使用它 以水平样式使用不同的文本视图。将该产品价格的样式设置为粗体。-非常糟糕的做法 使用SpannableString-但

我想将文本的某些部分设置为粗体,其值是使用ViewModel的数据绑定设置的

例如

如果您被选中,您将为您的一双鞋支付160美元

我正在使用字符串资源

如果您被选中,您必须为您的配对支付$%d。


当前通过设置
Binding.setProductPrice(Object.getPrice())

我知道以下解决方案:但我想尝试使用数据绑定

  • 使用Html文本-但不想在代码中使用它
  • 以水平样式使用不同的文本视图。将该产品价格的样式设置为粗体。-非常糟糕的做法
  • 使用SpannableString-但不想在代码中使用它
但上述所有解决方案都是权宜之计

问题:

要尝试使用数据绑定功能,该功能可用于设置字符串某些部分的样式。就像SpannableString一样


使用数据绑定操作布局文件中的字符串

您可以使用绑定适配器和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 }"/>


祝你好运。

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

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

尝试添加基本Html标记
,如果您被选中,您必须为您的配对支付$%d]]>。

布局文件:导入的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>

您必须创建一个
BindingAdapter
SpannableStringBuilder

绑定适配器

XML



可能对您有所帮助。

使用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}"
   />

随着Html.fromHtml签名在API级别24(Android N)上的更改,Android团队引入了HtmlCompat,以便在任何API级别中使用相同的签名

因此,您应该使用HtmlCompat类:

HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY);
要使用它,您可以在项目的build.gradle中包括AndroidX core:

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>


@pskink:我不想将完整的SpannableString或String传递给TextView。其思想是将textstyle应用于文本的某些部分。谢谢你的建议。@pskink:是的,这是最后一个选项(通过SpannableString/SpannableStringBuilder)。但是我们不能使用数据绑定应用样式吗?@pskink:使用数据绑定返回
SpannableStringBuilder
SpannableString
。但是,这就是字符串的操作在java/kotlin的代码中。我想使用数据绑定操作布局文件中的
String
。为什么这不只是向字符串资源添加
标记的问题:
如果您被选中,您将不得不为您的配对支付$%d。
?这对任意更改(例如前景色)不起作用,但对于黑体字则可以。“我想使用数据绑定操作布局文件中的字符串。”--这并不实际,因为您没有完整的多语句编程语言。某些内容必须是Java/Kotlin格式,至少是
BindingAdapter
或其他帮助程序代码的级别。@Commonware:已尝试向字符串资源添加标记:
如果您被选中,您必须为您的代码对支付$%d。
。但文本仍然没有格式化。尝试使用
如果您被选中,您必须为您的配对支付$%d]]>
。它仍然显示相同的结果,未格式化的纯文本。喜欢你的解决方案。尽管我们仍然在代码中操作。调用
格式(视图,sdfgsdfg,12)
。您的解决方案只是调用一个方法,该方法确实具有BindingAdapter的注释,但在这里这是无用的。因为我们仍在使用TexView.setText。我真的希望避免传递textview并在代码中对其进行操作。我的最终目标是充分利用数据绑定并避免代码中的所有操作。@Vikalpatel除非该视图中定义了具有此特定功能的方法,否则您必须在代码中对其进行操作。数据绑定只是将数据与视图绑定在一起。据我所知,除非您定义绑定适配器之类的东西,或者将数据传递给另一个方法进行处理,否则它不会格式化数据。祝你好运。@rbd_sqrl:是的,我知道数据绑定只是将数据与视图绑定。但我的想法是充分探索数据绑定。是的,我们可以使用Spanable。感谢您提供解决方案:)@pskink:Yes,应该避免使用
Html.fromHtml
。但我不想在代码中操纵它。这是我使用数据绑定实现的最终目标。将在找到其他最佳解决方案时更新答案。@pskink:到目前为止,我只使用
string
资源
@string/xxxxx
android:text=“@{Html.fromHtml(@string/product_price(productPrice))}”
“但我不想在代码中操作它”
-而且
Html.fromHtml
不是java代码吗?我已经用simple
SpannableString
为您提供了一个解决方案,但您仍然认为
Html.fromHtm
不需要任何java代码,并且比simple
setSpan
方法更好/更快-这就是为什么我否决了您的建议answer@pskink:是的,
Html.fromHtml
在内部运行java代码。但我不必编写java代码,它在幕后做什么,我现在不太关心这一点。但是的,将来肯定会使用您的解决方案。你否决了我的答案,这很好。
“但我不必编写java代码,它在幕后做的事情”
,它只有3行代码(是的,3行)-创建
样式span
,设置span并调用
TextUtils#expandTemplate
-现在将它与正在做的事情进行比较-当然真正的工作是在
  <androidx.appcompat.widget.AppCompatTextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" 
        android:text="@{model.value}"
        app:setBold="@{model.isBold}"
   />
HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY);
implementation 'androidx.core:core:1.3.1'
<?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>