Vectordrawable - Is It Available Somehow for Pre-Lollipop Versions of Android

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 to
app: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



Leave a reply



Submit