VectorDrawable - is it available somehow for pre-Lollipop versions of Android?
UPDATE ON March 2016
By Android Support Library 23.2.1 update, Support Vector Drawables and Animated Vector Drawables. (you can also use latestone for the same)
Please update version of a library in gradle file.
compile 'com.android.support:recyclerview-v7:23.2.1'
Vector drawables allow you to replace multiple png assets with a single vector graphic, defined in XML. While previously limited to Lollipop and higher devices, both VectorDrawable
and AnimatedVectorDrawable
are now available through two new Support Libraries support-vector-drawable and animated-vector-drawable. new app:srcCompat
attribute to reference vector drawables .
Check source on github with some sample examples.
Changes for v7 appcompat library:
Reverted dependency on vector assets so that developers using the appcompat library are not forced to use VectorDrawable
and its associated build flags.
Android vector compatibility
From Android 5.0 (API level 21) you can use vector drawable in your app. You can use new Android Studio tool called: Vector Asset Studio. It handles PNG making for older versions automatically. See link below for a complete explanation:
Vector Asset Studio
How to properly use backwards compatible Vector Drawable with the latest Android Support Library?
Add the latest support lib to your app's build.gradle
dependencies:
compile 'com.android.support:appcompat-v7:26.0.2'
and add the following line in the same file:
android {
...
defaultConfig {
...
vectorDrawables.useSupportLibrary = true
}
...
}
Import vector image through Vector Asset Studio.
That's all, you are ready to go!
ImageView
XML
Use app:srcCompat
attribute instead of android:src
:
<ImageView
...
app:srcCompat="@drawable/your_vector"
... />
Programmatically
Directly from resource id:
imageView.setImageResource(R.drawable.your_drawable);
Set as Drawable
object (e.g. for tinting):
Drawable vectorDrawable
= AppCompatResources.getDrawable(context, R.drawable.your_vector);
imageView.setImageDrawable(vectorDrawable);
And if you want to set tint:
DrawableCompat.setTint
(vectorDrawable, ContextCompat.getColor(context, R.color.your_color));
TextView drawable
XML
There is no simple solution: XML attribute android:drawableTop(Bottom etc)
can't handle vector images on pre-Lollipop. One solution is to add initializer block to activity and wrap vector into another XML drawable. Second - to define a custom TextView.
Programmatically
Setting resource directly doesn't work, you have to use Drawable
object. Get it the same way as for ImageView
and set it with the appropriate method:
textView.setCompoundDrawablesWithIntrinsicBounds(vectorDrawable, null, null, null);
Menu icon
There is nothing special:
<item
...
android:icon="@drawable/your_vector"
... />
menuItem.setIcon(R.drawable.your_vector);
Notifications:
It's impossible, you have to use PNGs :(
How to use vector drawables with View besides ImageView with srcCompat?
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>
UPDATE
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());
}
Glide placeholder vector drawable resource not found exception
Try to get the drawable using ContextCompat
and set it as placeholder:
ContextCompat.getDrawable(mContext, placeHolderResDrawable);
So it would be:
Glide.with(mContext)
.load(resDrawable)
.placeholder(ContextCompat.getDrawable(mContext, placeHolderResDrawable))
.centerCrop()
.bitmapTransform(new CropCircleTransformation(MyLruBitmapPool.getInstance()))
.into(imgRoundedView);
Update for Glide v4:
Glide.with(mContext)
.load(resDrawable)
.apply(new RequestOptions()
.placeholder(ContextCompat.getDrawable(mContext, placeHolderResDrawable))
.centerCrop()
.transform(new CropCircleTransformation(MyLruBitmapPool.getInstance())))
.into(imgRoundedView);
InflateException: Error inflating class ImageView for VectorDrawableCompat
I believe the problem is android:src="@drawable/mypic"
in your imageView setup.
Change that toapp:srcCompat="@drawable/mypic"
Then you should be good to go.
More details, please refer to:
https://medium.com/@chrisbanes/appcompat-v23-2-age-of-the-vectors-91cbafa87c88#.mvuq06x1k
Invalid drawable tag vector
The problem was that my activity wasn't extending AppCompatActivity
but regular Activity
.
This is not specified in any documentation/example for support vector drawables
Vector drawables that are automatically converted to pngs
Google is starting to provide material design icons in the VectorDrawable xml format.
The git repository is hosted here:
https://github.com/google/material-design-icons
At the start of Google I/O Material design icons in VectorDrawable xml format were added to the repository (along with other updates documented here). They are located in folders named drawable-anydpi-v21
. For example, here are the communication icons in xml.
Here is what Google's comments say about the addition of these new Vector Drawables:
Add a first cut at some Vector Drawables for these icons.
Only black, 24dp vector drawables are included.
We fully expect these icons to work correctly, how they should be
considered 'beta' until we've more fully fleshed out the best
practices for using them.
Update: The post announcing Android Studio 1.3 being promoted to beta states that vector rasterization support is still not enabled due to various bugs.
Related Topics
Support Fragmentpageradapter Holds Reference to Old Fragments
How to Make Constraintlayout Work with Percentage Values
Sending Text Messages Programmatically in Android
Why Are Most UI Frameworks Single Threaded
Intent Action for Network Events in Android Sdk
Could Not Find Com.Android.Tools.Build:Aapt2:3.2.0
Some Androids Apps Won't Connect Through Fiddler
Preferencefragmentcompat Requires Preferencetheme to Be Set
How to Add a Library (Android-Support-V7-Appcompat) in Intellij Idea
Changing Background Color of Selected Item in Recyclerview
How to Add an Android Studio Project to Github
HTML Email Looking Different in Gmail App
Recyclerview Itemtouchhelper Buttons on Swipe
Android: Clear Cache of All Apps
Firebase (Fcm): Open Activity and Pass Data on Notification Click. Android