对于 Lollipop 之前的设备,Android Studio Vector Assets 工具将矢量可绘制对象转换为 PNG-s,但我得到的 PNG-s 质量非常差,您可以在此处看到:
此外,按钮的背景纯色应该是您在左侧看到的浅绿色,但可绘制对象会覆盖它:
<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>
drawable 的 xml 是( Material 图标的默认值):
<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"/>
我还想通过调整值使图标看起来小一点,我注意到增加视口(viewport)尺寸会减小图标,但我不确定我是否理解原因。
那么:如何使图标和生成的 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"
/>
结果是:
我设法通过增加矢量可绘制对象的宽度和高度来减少模糊。然而,如果没有 android:top|bottom|left|right
标签,drawable 将被拉伸(stretch)到按钮的整个区域。第二个按钮不需要背景纯色,所以我没有使用图层列表标签 => 无法为可绘制对象设置 top|bottom|left|right
边距。
如果我减小按钮尺寸,我所做的就是减小按钮的可点击区域。
我更新的问题是如何在不减小按钮本身大小的情况下设置按钮/切换按钮/单选按钮内可绘制矢量的大小?
更新
我找不到在 API 21 之前的设备上调整矢量可绘制对象大小的方法。因此,我将按钮本身做得更小,并增加了每个按钮的触摸区域。
最佳答案
缩放任何可绘制对象的正确方法是使用 vectorDrawable.setBounds(left,top,right,bottom)
,
但不幸的是,这不适用于矢量绘图(为什么是 Google?)。
作为一种解决方法,我加载了我的矢量可绘制对象,将它们转换为位图可绘制对象,这将允许我们在位图可绘制对象上使用 setBounds
方法。请注意,您在此处缩放位图,因此可能会损失一些图像的清晰度。例如,当我需要将我的可绘制对象用作 TextView 或按钮的复合可绘制对象时,我主要使用这些方法。
我最终编写了一个辅助类,它将加载一个矢量可绘制对象并为其设置色调,并返回一个位图可绘制对象,您可以根据需要实际缩放和着色。我已经针对 API 级别 19 到 23 对其进行了测试,它可以正常工作。
不要忘记在您的 build.gradle 中使用 vectorDrawables.useSupportLibrary = true
。
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;
}
}
现在我会像这样使用这个辅助类:
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);
重要的是使用 View 或 Activity 的上下文,而不是应用程序上下文! 希望它能解决您的问题,或帮助其他人。如果有人有更好更清洁的解决方案,我也很想知道。
关于android - 如何在 Android 中设置按钮内可绘制矢量的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33691077/