app:srcCompat
with ImageView
allows for backward compatible use of vector drawables. But how can you use them with other View
s besides
Form android studio 3.0.0 android:src is not support vector image and below 21 my get exception. use app:srcCompat for vector image. Keep all vector image files inside the drawable folder.
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
And in application class define this:
@Override
public void onCreate() {
super.onCreate();
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
Now you can use your .xml file. Don't forget to user this link: xmlns:app="http://schemas.android.com/apk/res-auto"
<RelativeLayout
android:id="@+id/counterValuePanel"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_cart_notify"/>
</RelativeLayout>
Now you can use app:srcCompat="@drawable/ic_cart_notify" but if you try to use in android:background or android:drawableLeft then you got "Error inflating" exception. For that create a new wrapped drawable .xml file, ic_cart_notify is vector icon.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_cart_notify"/>
</layer-list>
Dadou is right. So if you would like use selector for view with VectorDrawables you need to add:
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(trfor);
}
to every Activity where you want to use VectorDrawables on devices with versions below Android 5.
For AppCompat version 23.3.0 where no work solution via selector XML (razzledazzle's accepted answer) we can do this by programmatically:
activity_main.xml
<android.support.v7.widget.AppCompatImageButton
android:id="@+id/btnEnter"
/>
MainActivity.java
AppCompatImageButton image = (AppCompatImageButton) findViewById(R.id.btnEnter);
if (image != null) {
VectorDrawableCompat vcAccept = VectorDrawableCompat.create(getResources(), R.drawable.vc_accept, getTheme());
VectorDrawableCompat vcAcceptWhite = VectorDrawableCompat.create(getResources(), R.drawable.vc_accept_white, getTheme());
StateListDrawable stateList = new StateListDrawable();
stateList.addState(new int[]{android.R.attr.state_focused, -android.R.attr.state_pressed}, vcAccept);
stateList.addState(new int[]{android.R.attr.state_focused, android.R.attr.state_pressed}, vcAcceptWhite);
stateList.addState(new int[]{-android.R.attr.state_focused, android.R.attr.state_pressed}, vcAcceptWhite);
stateList.addState(new int[]{}, vcAccept);
image.setImageDrawable(stateList);
}
This code is equivalent for this selector xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="false" android:drawable="@drawable/vc_accept" />
<item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/vc_accept_white" />
<item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/vc_accept_white" />
<item android:drawable="@drawable/vc_accept" />
</selector>
If the vector drawable is not shown using API 23, you'll need to convert the VectorDrawable
to a regular Drawable
first. If you want to use setCompoundDrawablesWithIntrinsicBounds
you'll need to do this, but for StateListDrawable I didn't need to.
Drawable icon;
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
icon = VectorDrawableCompat.create(getResources(), R.drawable.vc_icon, getContext().getTheme());
} else {
icon = getResources().getDrawable(R.drawable.vc_icon, getContext().getTheme());
}