DataBinding:如何通过动态ID获取资源?

Dmi*_*sev 33 android android-databinding

我知道可以通过资源ID引用布局中的资源:

android:text="@{@string/resourceName}"
Run Code Online (Sandbox Code Playgroud)

但是,我想通过id引用资源,这只在运行时才知道.举个简单的例子,假设我们有这样的模型:

public class MyPOJO {

    public final int resourceId = R.string.helloWorld;

}
Run Code Online (Sandbox Code Playgroud)

现在我需要将此值用作格式字符串中的值.我们称之为

<string name="myFormatString">Value is: %s</string>
Run Code Online (Sandbox Code Playgroud)

最直接的方法不起作用:

android:text="@{@string/myFormatString(myPojo.resourceId)}"
Run Code Online (Sandbox Code Playgroud)

这只会将整数值放入占位符(也证明我正确初始化了我的POJO,所以我不在这里提供整个布局).

我也试过使用@BindingConversion,但它没有用(实际上是预期的,但我还是试过了) - int仍然分配给占位符并且没有调用绑定方法.

如何通过DataBinding库中的id显式获取资源?

Ama*_*i82 23

另一种解决方案是@BindingAdapter为它创建一个自定义.

@BindingAdapter({"format", "argId"})
public static void setFormattedText(TextView textView, String format, int argId){
    if(argId == 0) return;
    textView.setText(String.format(format, textView.getResources().getString(argId)));
}
Run Code Online (Sandbox Code Playgroud)

然后分别提供变量.

<TextView
    app:format="@{@string/myFormatString}"
    app:argId="@{myPojo.resourceId}"
Run Code Online (Sandbox Code Playgroud)

如果你需要多个参数,你可以使用数组,但在我的情况下,一个就足够了.


Kas*_*asi 18

截至2016年6月,这可以用XML:

android:text= "@{String.format(@string/my_format_string, myPojo.resourceId)}"
Run Code Online (Sandbox Code Playgroud)

  • 它返回resourceId (2认同)

Dmi*_*sev 11

我最终创建了自己的方法:

public class BindingUtils {

    public static String string(int resourceId) {
        return MyApplication
                .getApplication()
                .getResources()
                .getString(resourceId);
    }

}
Run Code Online (Sandbox Code Playgroud)

声明导入:

<data>

    <import type="com.example.BindingUtils" />

    ...

</data>
Run Code Online (Sandbox Code Playgroud)

并在绑定期间调用它:

android:text="@{@string/myFormatString(BindingUtils.string(myPojo.resourceId))}"
Run Code Online (Sandbox Code Playgroud)

为此提供开箱即用的方法会很高兴.DataBinding正处于测试阶段 - 所以未来可能会出现这种情况.


Khe*_*raj 7

另一个解决方案,如果你 已经Context在 xml 中定义了那么您将不需要导入String类。

android:text="@{@string/myFormatString(context.getString(pojo.res))}"
Run Code Online (Sandbox Code Playgroud)

会为

<string name="myFormatString">Value is: %s</string>
Run Code Online (Sandbox Code Playgroud)

如果您的 xml 中没有上下文。然后按照这个

<data>    
     <variable
         name="context"
         type="abc.UserActivity"/>

     <variable
         name="pojo"
         type="abc.MyPOJO"/>
 </data>
Run Code Online (Sandbox Code Playgroud)

并且在你的 Activity

ActivityUserBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_user);
binding.setPojo(new MyPOJO());
binding.setContext(this);
Run Code Online (Sandbox Code Playgroud)

  • `context` 就在那里,不需要导入 (7认同)

Dal*_*ngh 6

您可以使用:

android:text='@{(id > 0) ? context.getString(id) : ""}'
Run Code Online (Sandbox Code Playgroud)