Data Binding with srcCompat

AndroidAndroid Support-LibraryAndroid Databinding

Android Problem Overview


I'm using the new vector drawable support in Support Lib v23.2 with app:srcCompat & trying to set its drawable via data binding.

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
    <variable
        name="mediaPojo"
        type="in.ishaan.pika.data_binding.MediaPojo"/>
</data>

<RelativeLayout
    android:background="@color/black"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <VideoView
        ... />

    <ImageView
        ...
        app:srcCompat="@{mediaPojo.isPlaying ? @drawable/ic_pause_24dp : @drawable/ic_play_arrow_24dp}"
    />

    <ProgressBar
        .../>
</RelativeLayout>
</layout>

On trying to build, studio throws:

> Error:(33, 30) Cannot find the setter for attribute 'app:srcCompat' with parameter type android.graphics.drawable.Drawable.

Android Solutions


Solution 1 - Android

You can simply use android:src attribute instead compat attribute when you set vector resource by DataBinding.

DataBinding library generates class that execute setImageResource method at runtime.

<ImageView
        ...
        android:src="@{@drawable/your_drawable}"
/>

According to http://android-developers.blogspot.com/2016/02/android-support-library-232.html setImageResource method can be used at runtime on older system versions without any additional changes.

If you would like to use app:srcCompat attribute. You must define @BindingMethods annotation which connects attribute with appropriate setter from ImageView. For example in your Activity or Fragment add.

@BindingMethods({
    @BindingMethod(type = android.widget.ImageView.class,
            attribute = "app:srcCompat",
            method = "setImageDrawable") })
public class MainActivity extends AppCompatActivity {
   // your activity body here

}

Solution 2 - Android

You may have to resort to using a binding adapter with a method signature similar to the following:

@BindingAdapter("app:srcCompat")
public static void bindSrcCompat(ImageView imageView, Drawable drawable){
    // Your setter code goes here, like setDrawable or similar
}

Here is the reference: http://developer.android.com/reference/android/databinding/BindingAdapter.html

Solution 3 - Android

The proposed answers mainly worked for me but I also needed to add this line in my Application:

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);

Doing so allows me to use vector drawables in older versions without needing to worry about compat classes or attributes

Solution 4 - Android

if you need to use srcCompat and also need to set a tint via xml on your drawables the easiest way is to use android.support.v7.widget.AppCompatImageView

And then android:tint and app:srcCompat work just fine.

note: for some reason unknown to me in fragment layouts using ImageView works fine. Reverting to AppCompatImageView is only necessary in activity layouts.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIshaan GargView Question on Stackoverflow
Solution 1 - AndroidlukjarView Answer on Stackoverflow
Solution 2 - AndroidSeptimusX75View Answer on Stackoverflow
Solution 3 - AndroidgattiView Answer on Stackoverflow
Solution 4 - AndroidRik van VelzenView Answer on Stackoverflow