在android中使用数据绑定在android:src中为ImageView设置drawable资源ID

我试图设置可绘制的资源ID到android:使用数据绑定ImageView的src

这是我的目标:

public class Recipe implements Parcelable { public final int imageResource; // resource ID (eg R.drawable.some_image) public final String title; // ... public Recipe(int imageResource, String title /* ... */) { this.imageResource = imageResource; this.title = title; } // ... } 

这是我的布局:

 <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="recipe" type="com.example.android.fivewaystocookeggs.Recipe" /> </data> <!-- ... --> <ImageView android:id="@+id/recipe_image_view" android:layout_width="match_parent" android:layout_height="200dp" android:scaleType="centerCrop" android:src="@{recipe.imageResource}" /> <!-- ... --> </layout> 

最后,活动课:

 // ... public class RecipeActivity extends AppCompatActivity { public static final String RECIPE_PARCELABLE = "recipe_parcelable"; private Recipe mRecipe; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mRecipe = getIntent().getParcelableExtra(RECIPE_PARCELABLE); ActivityRecipeBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_recipe); binding.setRecipe(mRecipe); } // ... } 

它根本不显示图像。 我究竟做错了什么?

顺便说一句,它完全符合标准的方式:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recipe); final ImageView recipeImageView = (ImageView) findViewById(R.id.recipe_image_view); recipeImageView.setImageResource(mRecipe.imageResource); } 

2016年11月10日前答复

Splash的下面的评论强调,没有必要使用自定义属性types(如imageResource ),我们可以创build多个方法为android:src像这样:

 public class DataBindingAdapters { @BindingAdapter("android:src") public static void setImageUri(ImageView view, String imageUri) { if (imageUri == null) { view.setImageURI(null); } else { view.setImageURI(Uri.parse(imageUri)); } } @BindingAdapter("android:src") public static void setImageUri(ImageView view, Uri imageUri) { view.setImageURI(imageUri); } @BindingAdapter("android:src") public static void setImageDrawable(ImageView view, Drawable drawable) { view.setImageDrawable(drawable); } @BindingAdapter("android:src") public static void setImageResource(ImageView imageView, int resource){ imageView.setImageResource(resource); } } 

老答案

您可以随时尝试使用适配器:

 public class DataBindingAdapters { @BindingAdapter("imageResource") public static void setImageResource(ImageView imageView, int resource){ imageView.setImageResource(resource); } } 

然后你可以像这样在你的xml中使用适配器

 <ImageView android:id="@+id/recipe_image_view" android:layout_width="match_parent" android:layout_height="200dp" android:scaleType="centerCrop" imageResource="@{recipe.imageResource}" /> 

一定要注意,XML中的名称与BindingAdapter注释(imageResource)

DataBindingAdapters类不需要在特定的任何地方进行声明,DataBinding机制会发现它无论(我相信)

定义:

 @BindingAdapter({"android:src"}) public static void setImageViewResource(ImageView imageView, int resource) { imageView.setImageResource(resource); } 

使用:

 <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:scaleType="center" android:src="@{viewModel.imageRes, default=@drawable/guide_1}"/> 
 public Drawable getImageRes() { return mContext.getResources().getDrawable(R.drawable.icon); } <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="center" android:src="@{viewModel.imageRes}"/> 

使用壁画(facebook图像库)

  public class YourCustomBindingAdapters { //app:imageUrl="@{data.imgUri}" @BindingAdapter("bind:imageUrl") public static void loadImage(SimpleDraweeView imageView, String url) { if (url == null) { imageView.setImageURI(Uri.EMPTY); } else { if (url.length() == 0) imageView.setImageURI(Uri.EMPTY); else imageView.setImageURI(Uri.parse(url)); } } } 

对于Kotlin把它放在顶级的utils文件中,不需要静态/伴随上下文:

 @BindingAdapter("android:src") fun setImageViewResource(view: ImageView, resId : Int) { view.setImageResource(resId) } 

切勿在创build自己的@BindingAdapter时覆盖标准的SDK属性!

这不是一个好方法,原因很多:它会阻止获得该属性上的Android SDK更新的新修补程序的好处。 也可能会让开发人员感到困惑,而且对于可重用性来说也是非常棘手的(因为它没有被检测到被忽略)

你可以使用不同的命名空间,如:

 custom:src="@{recipe.imageResource}" 

要么

 mybind:src="@{recipe.imageResource}" 

不过,我会推荐不同的解决scheme:

 android:src="@{ContextCompat.getDrawable(context, recipe.imageResource)}" 

上下文视图始终在绑定块@{ ... }可用