Tomblarom
Tomblarom

Reputation: 1458

VectorDrawable is scaled and unsharp

Vector xml in Android Studio:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
    android:fillColor="#FF000000"
    android:pathData="M12,15C7.58,15 4,16.79 4,19V21H20V19C20,16.79 16.42,15 12,15M8,9A4,4 0,0 0,12 13A4,4 0,0 0,16 9M11.5,2C11.2,2 11,2.21 11,2.5V5.5H10V3C10,3 7.75,3.86 7.75,6.75C7.75,6.75 7,6.89 7,8H17C16.95,6.89 16.25,6.75 16.25,6.75C16.25,3.86 14,3 14,3V5.5H13V2.5C13,2.21 12.81,2 12.5,2H11.5Z" />

The result:

enter image description here

Changing 24dp to 96dp, result:

enter image description here

Menu xml in Android Studio:

...
<!-- Sperren -->
<TextView
    android:id="@+id/suppress_button"
    style="@style/TextAppearance.MaterialSheetFab.Sheet.Item"
    android:drawableLeft="@drawable/ic_assignment_return"
    android:drawableStart="@drawable/ic_assignment_return"
    android:text="Sperren" />

 <!-- IH-Auftrag -->
 <TextView
    android:id="@+id/setup_maintenance_order_button"
    style="@style/TextAppearance.MaterialSheetFab.Sheet.Item"
    android:drawableLeft="@drawable/ic_ih_auftraege"
    android:drawableStart="@drawable/ic_ih_auftraege"
    android:text="IH-Auftrag" />
    ...

So my question now is, how to change the size automatically like a svg normally should do?

Upvotes: 1

Views: 1775

Answers (1)

racs
racs

Reputation: 4144

I am not quite sure this is the answer you were looking for, but here it goes anyway:

In short: use ImageView with scaleType="fitXY" and set up the size you want or create your own subclass and set dimensions on the Drawable as described below.

ImageView with the same vector drawable, scale type is fitCenter on the left, fitXY on the right:

ImageView example

Long description of the issue:

Your problem might come from the fact that numerous Android components are using Drawable instance assuming it has static dimensions.
These components are trying to get the actual dimensions of the Drawable by calling Drawable#getIntrinsicHeight() and Drawable#getIntrinsicWidth(). These methods will serve the exact amounts you have defined in your VectorDrawable resource as height and width respectively.
If these dimensions do not fit the required dimensions of the rectangle where the rendering goes then (usually) these components are applying a scaling Matrix on the Canvas before rendering the Drawable. The Drawable doesn't know anything about that it must be rendered into different dimension and renders the vector into a Bitmap with the dimensions you defined in the resource. After the Bitmap is ready with the vector content it will be rendered to the Canvas using scaling and (no surprise) it gets blurry.

Not all components are doing this luckily, for example ImageView is able to tell the Drawable that it needs to be rendered into different dimensions by calling [Drawable#setBounds()](http://developer.android.com/reference/android/graphics/drawable/Drawable.html#setBounds(int, int, int, int)), but only if the scale type is set to FitXY. (I had to peek into ImageView sources to figure this out.)
Unfortunately, this might not help in some cases. You can create your own subclassed component from these OS components and set the dimensions on the Drawable when you figure out the right dimensions.

Upvotes: 6

Related Questions