如何使用数据绑定将资源中的字符串与XML中的动态变量组合在一起?

我有一个TextView,它有一个硬编码的字符串,我有一个动态变量,我想把它放在这个字符串的末尾。这是我的代码:

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp">
<TextView
android:id="@+id/PeopleName"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/Generic_Text"+"@{ Profile.name }" />




</LinearLayout>

我的android:text="@string/Generic_Text"+"@{ Profile.name }"出现问题。Generic_Text声明“我的名字是”,则Profile.name是动态的,并且明显地从配置文件到配置文件而改变。我希望整个TextView输出我的名字是{profile.name}。任何帮助都很好。

100228 次浏览

你可以这样做:

android:text= "@{String.format(@string/Generic_Text, Profile.name)}"

如果对_ABC使用字符串格式,则_0字符串。例如,末尾的%s

你可以做得更简单:

android:text= "@{@string/generic_text(profile.name)}"

字符串应如下所示:

<string name="generic_text">My Name is %s</string>

编辑:

  1. 当然,您可以根据需要使用任意数量的变量:

    android:text= "@{@string/generic_text(profile.firstName, profile.secondName)}"
    
    
    <string name="generic_text">My Name is %1$s %2$s</string>
    
  2. It works just because it's designed in data binding. More in docs: https://developer.android.com/topic/libraries/data-binding/expressions#resources

如果您不能,请更改资源字符串以在末尾包含%s(例如,因为它在其他地方使用时没有后缀):

android:text="@{@string/Generic_Text.concat(Profile.name)}"

如果Profile.name不能为空,这就足够了。但是,如果发生null,它将崩溃。您必须添加另一层:

android:text="@{@string/Generic_Text.concat(Objects.toString(Profile.name))}"

(这需要<import type="java.util.Objects"/>才能工作。)

再次强调:只有当您在其他地方使用资源字符串时,所有这些额外的工作才是值得的。第二个原因是,当您希望将null处理为“空字符串”而不是“ null ”文字时。

连接字符串的多种方法

使用字符串资源(推荐,因为本地化

android:text= "@{@string/generic_name(user.name)}"

只需像这样创建字符串资源。

<string name="generic_name">Hello %s</string>

2.硬编码的Concat

android:text="@{`Hello ` + user.name}"/>

当您需要为电话号码添加类似+的硬编码时,这很有用。

使用String的CONCAT方法

android:text="@{user.firstName.concat(@string/space).concat(user.lastName)}"

这里,space是放置在strings.xml内的HTML实体。因为XML不直接接受HTML实体或特殊字符。(链接HTML实体)

<string name="space">\u0020</string>

使用String.format()

android:text= "@{String.format(@string/Hello, user.name)}"

您必须在此类型的布局中导入字符串类。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="String" />
</data>
<TextView
android:text= "@{String.format(@string/Hello, user.name)}"
... >
</TextView>
</layout>

通过字符串资源连接两个字符串。

android:text="@{@string/generic_name(user.firstName,user.lastName)}"

在本例中,将字符串资源放在strings.xml

<string name="generic_name">%1$s, %2$s</string>

可以有很多其他的方法,选择一个你需要的。

2019年更新,Android Studio升级到3.4,Android Gradle插件升级到3.4

不再需要导入

<import type="java.lang.String" />"

用于字符串操作。请检查此回答

使用绑定适配器

此示例是用Kotlin编写的,并考虑到绑定变量可以为空:

@BindingAdapter("my_name")
fun TextView.setMyName(name: String?) {
this.text =
if (name.isNullOrEmpty()) "" else "${this.context.getString(R.string.Generic_Text)} $name"
}

然后在XML中使用绑定适配器,而不是android:text属性

app:my_name="@{Profile.name}"

如果要在XML中键入文本,则可以使用``报价。

android:text="@{`Device Name`}"

在其他地方,你需要与字符串或变量连接,你可以使用

android:text="@{`Device Name`.concat(android.os.Build.MANUFACTURER)}"

如果你想Concat字符串资源而不是你能做的变量,

android:text="@{@string/app_name.concat(`Device Name`)}"

我只使用+运算符:

android:text= "@{@string/Generic_Text +' '+ Profile.name)}"

String.XML将为:

<string name="Generic_Text">Hello</string>

您还可以使用如下所示的格式化程序将字符串资源设置为其他字符串资源的参数:

<string name="first_param_text">Hello</string>
<string name="second_param_text">World</string>
<string name="formatted_text">%s lovely %s</string>

android:text="@{String.format(@string/formatted_text, @string/first_param_text, @string/second_param_text)}"

“你好,可爱的世界”将显示在视图上。

只需放入或附加您的字符串资源名称,它将工作正常。

e.X@string/test

Android:text=";@{@string/test+viewmodel.name+@string/test}";

Strings.XML:<string name="my_string">Hello %s</string>

view.XML:android:text="@{@string/my_string(name)}"

yourViewBinding.yourTextView.setText(this.yourViewBinding.getRoot().getResources().getString(R.string.your_字符串)+yourStringVariable);