Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set drawable resource ID in android:src for ImageView using data binding in Android

I'm trying to set drawable resource ID to android:src of ImageView using data binding

Here is my object:

public class Recipe implements Parcelable {
    public final int imageResource; // resource ID (e.g. R.drawable.some_image)
    public final String title;
    // ...

    public Recipe(int imageResource, String title /* ... */) {
        this.imageResource = imageResource;
        this.title = title;
    }

    // ...
}

Here is my layout:

<?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>

And finally, activity class:

// ...

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);
    }

    // ...

}

It doesn't display image at all. What am I doing wrong?

BTW, it was perfectly working with standard way:

@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);

}
like image 468
Yuriy Seredyuk Avatar asked Mar 05 '16 02:03

Yuriy Seredyuk


2 Answers

Answer as of Nov 10 2016

Splash's comment below has highlighted that it is not necessary to use a custom property type (like imageResource), we can instead create multiple methods for android:src like so:

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);
    }
}

Old Answer

You could always try to use an adapter:

public class DataBindingAdapters {

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

You can then use the adapter in your xml like so

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

Be sure to notice that the name within the xml matches the BindingAdapter annotation (imageResource)

The DataBindingAdapters class doesn't need to be declared anywhere in particular, the DataBinding mechanics will find it no matter (i believe)

like image 109
Joe Maher Avatar answered Nov 07 '22 07:11

Joe Maher


There is no need for a custom BindingAdapter at all. Just use

app:imageResource="@{yourResId}"

and it will work fine.

Check this for how it works.

like image 94
hqzxzwb Avatar answered Nov 07 '22 08:11

hqzxzwb