Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
286 views
in Technique[技术] by (71.8m points)

android - Why isn't my vector drawable scaling as expected?

I am attempting to use vector drawables in my Android app. From http://developer.android.com/training/material/drawables.html (emphasis mine):

In Android 5.0 (API Level 21) and above, you can define vector drawables, which scale without losing definition.

Using this drawable:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="@color/colorPrimary" android:pathData="M14,20A2,2 0 0,1 12,22A2,2 0 0,1 10,20H14M12,2A1,1 0 0,1 13,3V4.08C15.84,4.56 18,7.03 18,10V16L21,19H3L6,16V10C6,7.03 8.16,4.56 11,4.08V3A1,1 0 0,1 12,2Z" />

and this ImageView:

<ImageView
    android:layout_width="400dp"
    android:layout_height="400dp"
    android:src="@drawable/icon_bell"/>

produces this blurry image when attempting to display the icon at 400dp (on a largish high-res circa 2015 mobile device running lollipop):

blurryBellIcon

Changing the width and height in the definition of the vector drawable to 200dp significantly improves the situation at the 400dp rendered size. However, setting this as a drawable for a TextView element (i.e. icon to the left of the text) now creates a huge icon.

My questions:

1) Why is there a width/height specification in the vector drawable? I thought the entire point of these is that they scale up and down losslessly making width and height meaningless in its definition?

2) Is it possible to use a single vector drawable which works as a 24dp drawable on a TextView but scales up well to use as much larger images too? E.g. how do I avoid creating multiple vector drawables of different sizes and instead use one which scales to my rendered requirements?

3) How do I effectively use the width/height attributes and what is the difference with viewportWidth/Height?

Additional details:

  • Device is running API 22
  • Using Android Studio v1.5.1 with Gradle version 1.5.0
  • Manifest is compile and target level 23, min level 15. I've also tried moving min level to 21, but this made no difference.
  • Decompiling the APK (with min level set to 21) shows a single XML resource in the drawable folder. No rasterized images are produced.
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There is new info about this issue here:

https://code.google.com/p/android/issues/detail?id=202019

It looks like using android:scaleType="fitXY" will make it scale correctly on Lollipop.

From a Google engineer:

Hi, Let me know if scaleType='fitXY' can be a workaround for you , in order to get the image look sharp.

The marshmallow Vs Lollipop is due to a special scaling treatment added into marshmallow.

Also, for your comments: " Correct behavior: The vector drawable should scale without quality loss. So if we want to use the same asset in 3 different sizes in our application, we don't have to duplicate vector_drawable.xml 3 times with different hardcoded sizes. "

Even though I totally agree this should be the case, in reality, the Android platform has performance concern such that we have not reach the ideal world yet. So it is actually recommended to use 3 different vector_drawable.xml for better performance if you are sure you want to draw 3 different size on the screen at the same time.

The technical detail is basically we are using a bitmap under the hook to cache the complex path rendering, such that we can get the best redrawing performance, on a par with redrawing a bitmap drawable.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...