如何设置Android中按钮内部矢量绘图的大小?

Val*_*a.V 9 xml android vector button drawable

Android Studio Vector Assets工具将矢量drawable转换为PNG-s用于Lollipop之前的设备,但是我得到了质量非常差的PNG-s,你可以在这里看到:

将矢量转换为PNG

更重要的是,按钮的背景纯色应该是您在左侧看到的浅绿色,但是可绘制的覆盖它:

<item android:state_checked="true"
    android:drawable="@drawable/show">
    <shape android:shape="rectangle">
        <corners android:bottomRightRadius="8dp"/>
        <solid android:color="@color/waveComponentGreen"/>
    </shape>
</item>

<item android:state_checked="false"
    android:drawable="@drawable/hide">
    <shape android:shape="rectangle">
        <corners android:bottomRightRadius="8dp"/>
        <solid android:color="@color/waveComponentGreen"/>
    </shape>
</item>
Run Code Online (Sandbox Code Playgroud)

drawable的xml是(材质图标的默认值):

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
<path
    android:fillColor="#FF000000"
    android:pathData="M8.59,16.34l4.58,-4.59 -4.58,-4.59L10,5.75l6,6 -6,6z"/>
Run Code Online (Sandbox Code Playgroud)

我还希望通过调整值使图标显得更小,我注意到增加视口尺寸会减小图标,但我不确定我理解为什么.

那么:如何使图标和生成的PNG看起来更小,更少模糊,并在资源文件中设置背景颜色?谢谢.

编辑:我通过将它们组合在一个带有图层列表的单独xml文件中,设法获得带有图标的纯色背景:

<layer-list
xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
    <shape android:shape="rectangle">
        <corners android:bottomRightRadius="10dp"/>
        <solid android:color="@color/waveComponentGreen"/>
    </shape>
</item>
<item android:drawable="@drawable/show"
    android:top="10dp"
    android:bottom="10dp"
    android:left="10dp"
    android:right="10dp"
    />
Run Code Online (Sandbox Code Playgroud)

结果是:

一些调整的结果

我设法通过增加矢量drawable的宽度和高度来减少模糊.但是,如果没有android:top|bottom|left|right标签,则可拉伸的按钮会拉伸整个按钮区域.第二个按钮不需要具有背景纯色,因此我没有使用layer-list标签=>无法top|bottom|left|right为drawable 设置边距.
如果我减小按钮大小,我正在做的是减少按钮的可点击区域.

我更新的问题是如何设置按钮/切换按钮/单选按钮内的矢量可绘制的大小而不减小按钮本身的大小?

更新
我无法找到一种方法来调整API 21之前的设备上的矢量可绘制的大小.因此,我将按钮本身缩小,增加了每个按钮的触摸区域.

Ive*_*ius 10

缩放任何drawable的正确方法是使用vectorDrawable.setBounds(left,top,right,bottom),但不幸的是,这不适用于矢量drawables(为什么是Google?).

因此,作为一种解决方法,我加载我的矢量drawables,将它们转换为位图drawable,这将允许我们setBounds在位图drawable上使用该方法.请注意,您在此处缩放位图,因此可能会丢失图像的清晰度.当我需要将drawable用作文本视图的复合可绘制或按钮时,我主要使用这些方法.

我最后编写了一个辅助类,它将加载一个矢量drawable设置一个色调并返回一个bitmap drawable,你可以根据需要实际缩放和着色.我已经测试了它的API级别19到23,它的工作原理.

不要忘记vectorDrawables.useSupportLibrary = truebuild.gradle中使用.

public class VectorDrawableUtils {

/**
 * Gets a Bitmap from provided Vector Drawable image
 *
 * @param vd VectorDrawable
 * @return Bitmap
 */
public static Optional<Bitmap> createBitmapFromVectorDrawable(final @NonNull Drawable vd) {
    try {
        Bitmap bitmap;
        bitmap = Bitmap.createBitmap(vd.getIntrinsicWidth(), vd.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        vd.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        vd.draw(canvas);
        return Optional.of(bitmap);
    } catch (OutOfMemoryError e) {
        Injector.getDependency(getContext(), IEventTracker.class).logHandledException(e);
        return Optional.empty();
    }
}

/**
 * Loads vector drawable and apply tint color on it.
 */
public static Drawable loadVectorDrawableWithTintColor(final @DrawableRes int vdRes,
                                                       final @ColorRes int clrRes,final Context context) {
    Drawable drawable = ContextCompat.getDrawable(context, vdRes);
    DrawableCompat.setTint(drawable, getContext().getResources().getColor(clrRes));
    return drawable;
}

/**
 * Converts given vector drawable to Bitmap drawable
 */
public static BitmapDrawable convertVectorDrawableToBitmapDrawable(final @NonNull Drawable vd) {
    //it is safe to create empty bitmap drawable from null source
    return new BitmapDrawable(createBitmapFromVectorDrawable(vd).get());
}

/**
 * Loads vector drawable , aplys tint on it and returns a wrapped bitmap drawable.
 * Bitmap drawable can be resized using setBounds method (unlike the VectorDrawable)
 * @param context Requires view context !
 */
public static Drawable loadVectorDrawableWithTint(
        final @DrawableRes int vectorDrawableRes, final @ColorRes int colorRes,final Context context) {
    Drawable vd = VectorDrawableUtils.loadVectorDrawableWithTintColor(vectorDrawableRes,
            colorRes, context);
    final BitmapDrawable bitmapDrawable = VectorDrawableUtils.convertVectorDrawableToBitmapDrawable(vd);
    ColorStateList tint = ContextCompat.getColorStateList(context,colorRes);
    final Drawable wrappedDrawable = DrawableCompat.wrap(bitmapDrawable);
    DrawableCompat.setTintList(wrappedDrawable,tint);
    return wrappedDrawable;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在我将使用这样的助手类:

    Drawable bd = VectorDrawableUtils.loadVectorDrawableWithTint(
                R.drawable.ic_dropdown, R.color.black,getContext());
        bd.setBounds(0, 0, textView.getMeasuredHeight(), textView.getMeasuredHeight());
        textView.setCompoundDrawablesWithIntrinsicBounds(null, null, bd, null);
Run Code Online (Sandbox Code Playgroud)

使用视图或活动的上下文,而不是应用程序上下文是很重要的!希望它能解决你的问题,或者帮助别人.如果有人有更好更清洁的解决方案,我也有兴趣知道.