リソースIDによってレイアウト内のリソースを参照できることがわかっています。
Android:text="@{@string/resourceName}"
ただし、実行時にのみ知られているidでリソースを参照したいと思います。簡単な例として、次のようなモデルがあると想像してください。
public class MyPOJO {
public final int resourceId = R.string.helloWorld;
}
そして今、この値をフォーマット文字列の値として使用する必要があります。それを呼び出しましょう
<string name="myFormatString">Value is: %s</string>
最も簡単なアプローチは機能しません。
Android:text="@{@string/myFormatString(myPojo.resourceId)}"
これは整数値をプレースホルダーに入れるだけです(また、POJOを正しく初期化したことを証明しているため、ここではレイアウト全体を提供していません)。
また、@BindingConversion
、しかし、それは機能しませんでした(実際は予想されていましたが、とにかく試しました)-int
はまだプレースホルダーに割り当てられ、バインディングメソッドは呼び出されませんでした。
DataBindingライブラリのIDでリソースを明示的に取得するにはどうすればよいですか?
私は自分のメソッドを作成することになりました:
public class BindingUtils {
public static String string(int resourceId) {
return MyApplication
.getApplication()
.getResources()
.getString(resourceId);
}
}
インポートの宣言:
<data>
<import type="com.example.BindingUtils" />
...
</data>
そして、バインド中にそれを呼び出すだけです:
Android:text="@{@string/myFormatString(BindingUtils.string(myPojo.resourceId))}"
そのためのすぐに使えるメソッドがあればいいでしょう。 DataBindingはベータ版です。したがって、将来的には提供される可能性があります。
別の解決策は、カスタム@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)));
}
そして、変数を個別に提供します。
<TextView
app:format="@{@string/myFormatString}"
app:argId="@{myPojo.resourceId}"
複数の引数が必要な場合は配列を使用できますが、私の場合は1つで十分です。
2016年6月現在、これはXMLで可能です。
Android:text= "@{String.format(@string/my_format_string, myPojo.resourceId)}"
次を使用できます。
Android:text='@{(id > 0) ? context.getString(id) : ""}'
既にContext
がありますがXMLで定義されている場合、別の解決策はString
をインポートする必要はありませんクラスです。
Android:text="@{@string/myFormatString(context.getString(pojo.res))}"
のために働く
<string name="myFormatString">Value is: %s</string>
XMLにコンテキストがない場合は、これに従ってください
<data>
<variable
name="context"
type="abc.UserActivity"/>
<variable
name="pojo"
type="abc.MyPOJO"/>
</data>
Activity
ActivityUserBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_user);
binding.setPojo(new MyPOJO());
binding.setContext(this);
Kotlinバージョン:
@BindingAdapter("template", "resId")
fun TextView.setFormattedText(template: String, resId: Int) {
if (template.isEmpty() || resId == 0) return
text = template.format(resources.getString(resId))
}
xmlで
<TextView
app:template="@{@string/myFormatString}"
app:resId="@{viewModel.resourceId}"/>