使用数据绑定为Button加载drawableLeft图像

时间:2017-05-23 21:18:48

标签: android data-binding

我有一个带有图标和文字的按钮。

enter image description here

这是通过以下代码实现的:

            <Button
                ...
                android:drawableLeft="@drawable/ghana"
                android:drawableStart="@drawable/ghana"
                android:text="@string/hint_ghana"

                 />

当我这样做时,数据绑定与文本一起使用但不与图标一起使用:

            <Button
                ...
                android:drawableLeft="@{countryOfResidence.thumbnail}"
                android:drawableStart="@{countryOfResidence.thumbnail}"
                android:text="@{countryOfResidence.countryName}"

                 />

结果如下:

enter image description here

我已经找到了解决方案,但找不到任何解决方案,因为大多数都专注于将图像加载到ImageView中。

我的Model类看起来像这样:

public class CountryOfResidence {

private String countryName;
private int thumbnail;


public CountryOfResidence(String countryName, int thumbnail) {
    this.setCountryName(countryName);
    this.setThumbnail(thumbnail);
}
....

在调用Activity的onCreate()方法中,我正在执行此操作

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ActivitySignUpBinding signUpBinding = DataBindingUtil.setContentView(this, R.layout.activity_sign_up);
    MyHandler myHandler = new MyHandler();
    signUpBinding.setMyHandler(myHandler);

    mViewFlipper = (ViewFlipper) findViewById(R.id.signUpViewFlipper);

    countryOfResidenceList = new ArrayList<>();
    countryOfResidenceList.add(new CountryOfResidence("Nigeria", R.drawable.nigeria));
    countryOfResidenceList.add(new CountryOfResidence("Ghana", R.drawable.ghana));
    countryOfResidenceList.add(new CountryOfResidence("Kenya", R.drawable.kenya));

    signUpBinding.setCountryOfResidence(countryOfResidenceList.get(1));

最后,我的布局中的数据标签看起来像这样

<data>

  ...
    <variable
        name="countryOfResidence"
        type="orem_tech.com.teylur.model.CountryOfResidence"/>
</data>

有什么建议吗?

4 个答案:

答案 0 :(得分:7)

您似乎将资源ID传递到android:drawableLeft属性而不是Drawable。默认情况下,android数据绑定会自动将整数转换为ColorDrawable,因为它假定它们是颜色。

有几种方法可以解决这个问题。第一种是添加方法:

public Drawable loadDrawable(Context context, int resourceId) {
    return context.getDrawable(resourceId);
}

然后像这样绑定它:

android:drawableLeft="@{MyUtil.loadDrawable(countryOfResidence.thumbnail)}"

您还可以将thumbnail改为Drawable而不是int

public final ObservableField<Drawable> thumbnail = new ObservableField<Drawable>();

您也可以创建自己的BindingAdapter来接受int参数。按照TextViewBindingAdapter中的示例:

@BindingAdapter({"android:drawableLeft"})
public static void setDrawableLeft(TextView view, int resourceId) {
    Drawable drawable = ContextCompat.getDrawable(view.getContext(), resourceId);
    setIntrinsicBounds(drawable);
    Drawable[] drawables = view.getCompoundDrawables();
    view.setCompoundDrawables(drawable, drawables[1], drawables[2], drawables[3]);
}

private static void setIntrinsicBounds(Drawable drawable) {
    if (drawable != null) {
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
    }
}

如果您执行上述操作,则无法使用数据绑定将整数颜色设置为drawable。如果要将其分开,可以使用其他(应用程序命名空间)属性。但是你可能不需要将彩色绘图设置为drawableLeft

答案 1 :(得分:0)

答案有点晚,但对于未来的求职者 如果可以更改模型

来自

private int thumbnail;

private Drawable thumbnail;

然后您可以将drawable直接传递给布局,而不是资源ID

您的模型将变为

public class CountryOfResidence {

private String countryName;
private Drawable thumbnail;


public CountryOfResidence(String countryName, Drawable thumbnail) {
    this.setCountryName(countryName);
    this.setThumbnail(thumbnail);
}
....

您可以像这样初始化列表

countryOfResidenceList = new ArrayList<>();
    countryOfResidenceList.add(new CountryOfResidence("Nigeria", ContextCompat.getDrawable(this, R.drawable.nigeria)));

这就是将模型发送到布局并加载可绘制的对象,通常像

<Button
                ...
                android:drawableLeft="@{countryOfResidence.thumbnail}"
                android:drawableStart="@{countryOfResidence.thumbnail}"
                android:text="@{countryOfResidence.countryName}"

                 />

答案 2 :(得分:0)

如果您将可绘制对象表示为 Int (DrawableRes),则可以使用以下方法:

https://docs.google.com/spreadsheets/d/<YOUR-FILE-ID>/edit#gid=0&fvid=1781225551

例如,可以用颜色完成同样的操作:

android:drawableStart="@{androidx.core.content.ContextCompat.getDrawable(context, config.icon)}"

在这种情况下会自动定义上下文。

答案 3 :(得分:0)

像这样为所有 TextView 创建 BindingAdapter

@BindingAdapter("setDrawableRight")
fun TextView.setDrawableRight(resourceId: Int) {
    val drawable = ContextCompat.getDrawable(context, resourceId)
    setIntrinsicBounds(drawable)
    val drawables = compoundDrawables
    setCompoundDrawables(drawables[0], drawables[1], drawable, drawables[3])
}

private fun setIntrinsicBounds(drawable: Drawable?) {
    drawable?.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
}

并以这种方式使用

app:setDrawableRight="@{R.drawable.ic_check_24}"

感谢乔治·芒特