【问题标题】:How do I use databinding to combine a string from resources with a dynamic variable in XML?如何使用数据绑定将来自资源的字符串与 XML 中的动态变量结合起来?
【发布时间】:2016-08-16 15:10:48
【问题描述】:

我有一个 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 输出是 My Name is {Profile.name}。任何帮助都会很棒。

【问题讨论】:

  • 你在使用数据绑定吗?
  • 是的,我正在使用数据绑定
  • 请添加您当前的java代码。

标签: android android-databinding


【解决方案1】:

你可以更简单地做到这一点:

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. 它之所以有效,是因为它是在数据绑定中设计的。更多文档:https://developer.android.com/topic/libraries/data-binding/expressions#resources

【讨论】:

  • 但如果数据还没有准备好(例如没有从网络加载),它会显示My Name is null
  • 在这种情况下,请先检查一下。 android:text= "@{profile == null ? @string/loading : @string/generic_text(profile.firstName, profile.secondName)}"
  • 最佳答案:)
【解决方案2】:

你可以这样做:

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

如果您对Generic_Text 字符串使用字符串格式。前任。 %s在最后

【讨论】:

  • 非常感谢,我刚刚把它放进去,它工作正常
  • 这不应该是公认的答案,因为这实际上不使用数据绑定功能来操作文本。
  • 同意@Darwind,请参阅my answer 了解使用绑定适配器的工作实现
  • @IgorGanapolsky 这个答案已经有 3 年以上的历史了,但肯定曾经工作过 - 你还记得你尝试过的时候出了什么问题吗?
【解决方案3】:

连接字符串的多种方法

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

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

像这样制作字符串资源。

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

2。硬编码连接

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

当您需要硬编码附加电话号码时,这很有用。

3。使用String的concat方法

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

这里的space 是一个html 实体,它被放置在strings.xml 中。因为XML 不直接接受 Html 实体或特殊字符。 (Link Html Entities)

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

4。使用String.format()

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

你必须在这种类型的布局中导入String类。

<?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>

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

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

在这种情况下,将字符串资源放入strings.xml

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

还有很多其他的方法,选择你需要的。

【讨论】:

  • 我收到错误“找不到标识符格式”
【解决方案4】:

使用Binding Adapter

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

@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 中的String 类已经提供了基本操作,因此此解决方案仅适用于根据您的要求进行高级字符串操作。但是,它并没有错。
【解决方案5】:

2019 年更新,Android studio 到 3.4,Android Gradle 插件到 3.4

不再需要导入

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

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

【讨论】:

    【解决方案6】:

    如果你想在 XML 中键入文本,你可以使用 `` 引号。

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

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

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

    如果你想连接字符串资源而不是你可以做的变量,

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

    【讨论】:

      【解决方案7】:

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

      <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)}"
      

      “你好可爱的世界”将出现在视图中。

      【讨论】:

        【解决方案8】:

        strings.xml:&lt;string name="my_string"&gt;Hello %s&lt;/string&gt;

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

        【讨论】:

          【解决方案9】:

          仅使用 + 运算符对我有用:

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

          String.xml 将是:

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

          【讨论】:

            【解决方案10】:

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

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

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

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

            (需要&lt;import type="java.util.Objects"/&gt; 才能工作。)

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

            【讨论】:

            • 如果字符串资源用在别处,何不干脆做一个新资源?
            【解决方案11】:

            只需输入或附加您的字符串资源名称即可正常工作

            e.x @string/test

            android:text="@{@string/test+viewModel.name+@string/test}"

            【讨论】:

              【解决方案12】:

              yourViewBinding.yourTextView.setText(this.yourViewBinding.getRoot().getResources().getString(R.string.your_string) + yourStringVariable);

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-08-22
                • 2023-03-26
                • 2021-07-13
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多