【问题标题】:Load drawableLeft image for Button using databinding使用数据绑定为 Button 加载 drawableLeft 图像
【发布时间】:2017-05-23 21:18:48
【问题描述】:

我有一个包含图标和文本的按钮。

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

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

                 />

这是结果:

我一直在寻找解决方案,但找不到任何解决方案,因为大多数人都专注于将图像加载到 ImageView 中。

我的模型类如下所示:

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>

有什么建议吗?

【问题讨论】:

    标签: android data-binding


    【解决方案1】:

    您似乎将资源 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());
        }
    }
    

    如果您执行上述操作,您将无法使用数据绑定将整数颜色设置为可绘制对象。如果你想分开它,你可以使用不同的(应用命名空间)属性。但是您可能不需要将颜色可绘制对象设置为drawableLeft

    【讨论】:

    • 这个解决方案对我有用,只是我不得不输入android:drawableLeft="@{MyUtil.loadDrawable(countryOfResidence.thumbnail)}"而不是android:drawableLeft="@{MyUtil.loadDrawable(context, countryOfResidence.thumbnail)}"
    【解决方案2】:

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

    来自

    private int thumbnail;
    

    private Drawable thumbnail;
    

    然后你可以直接将drawable传递给layout而不是resource 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}"
    
                     />
    

    【讨论】:

      【解决方案3】:

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

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

      同样可以用颜色来做,例如:

      android:textColor="@{androidx.core.content.ContextCompat.getColor(context, config.iconColor)}"
      

      在这种情况下,上下文是自动定义的。

      【讨论】:

        【解决方案4】:

        为所有这样的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}"
        

        感谢乔治·芒特

        【讨论】:

          猜你喜欢
          • 2019-11-15
          • 2018-02-01
          • 2021-08-08
          • 1970-01-01
          • 2019-12-30
          • 2021-06-05
          • 1970-01-01
          • 1970-01-01
          • 2014-06-28
          相关资源
          最近更新 更多