¿Cómo configurar el tamaño del vector dibujable dentro de un botón en Android?
Las herramientas de Android Studio Vector Assets convierten los dibujos vectoriales a PNG-s para los dispositivos pre-Lollipop, pero me sale muy mal calidad PNG-s como se puede ver aquí . Lo que es más es que el fondo del botón de color sólido se supone que es esta luz verde que se ve a la izquierda, pero el dibujable lo sobrescribe:
<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>
El xml para el dibujable es (el predeterminado de los iconos de material):
- Error al analizar XML: prefijo no enlazado con barra de herramientas sdk 21
- cómo hacer que el diseño haga clic de forma programable
- Implementación de SeekBar simple en android
- Centrar un botón en un diseño Lineal
- Android ScrollView establece la altura del contenido visualizado
<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"/>
También quería hacer que el icono aparezca un poco más pequeño ajustando los valores y noté que el aumento de las dimensiones de la ventana disminuye el icono pero no estoy seguro de entender por qué.
Entonces: ¿Cómo puedo hacer que el icono y el PNG generado parezcan más pequeños, menos borrosos y con el color de fondo establecido en el archivo de recursos? Gracias.
EDIT : Me las arreglé para obtener el fondo de color sólido con el icono mediante la combinación de ellos en un archivo xml separado con capas de listas:
<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" />
El resultado está aquí . Me las arreglé para reducir el desenfoque mediante el aumento de la anchura y la altura del vector drawable.However sin el androide: top | bottom | left | derecho etiquetas el dibujable se extiende a través de todo el área del botón. El segundo botón no necesita tener un color sólido de fondo por lo que no estoy usando las etiquetas de la lista de capas => no hay forma de establecer un margen superior | inferior | izquierdo | derecho para el dibujable. Si reduzco el tamaño del botón, lo que estoy haciendo es reducir el área de clic del botón.
Mi pregunta actualizada es cómo establecer el tamaño del vector dibujable dentro de un botón / botón de conmutación / botón de radio sin reducir el tamaño del botón en sí?
ACTUALIZACIÓN No pude encontrar una forma de cambiar el tamaño del vector dibujable en dispositivos pre-API 21. Así que en su lugar he hecho los botones en sí más pequeños y aumentó el área táctil de cada botón.
- El inicio de Android Studio está tardando mucho
- Android - java.lang.UnsupportedOperationException: No se puede convertir a dimension: type = 0x12
- Cómo crear gradiente como Iphone Edittext cuadro en android
- Eliminar icono / logotipo de la barra de acción de android
- ListFragment aparece dos veces en el teléfono
- Hacer formas dinámicas (el mejor enfoque)
- Intellij IDEA formatea XML con atributos de alineación
- TextView no se desplaza suavemente
El enfoque correcto para escalar cualquier dibujable sería usar vectorDrawable.setBounds(left,top,right,bottom)
, pero desafortunadamente eso no funciona para drawables de vectores (¿por qué Google?).
Por lo tanto, como una solución, yo cargar mi vector drawables, convertirlos en mapa de bits dibujable y que nos permitirá utilizar el método setBounds
en el mapa de bits dibujable. Ten en cuenta que estás escalando mapas de bits aquí, por lo que puedes perder algo de nitidez de la imagen. Utilizo principalmente esos métodos cuando necesito utilizar mi drawable como un compuesto drawable de una opinión del texto o de un botón por ejemplo.
Terminé escribiendo una clase del ayudante que cargará un vector drawable fijó un tinte a él y devuelvo un mapa de bits drawable que usted puede realmente escala y tinte como usted desea. Lo he probado para niveles API de 19 hasta 23, y funciona.
No te olvides de usar vectorDrawables.useSupportLibrary = true
en tu build.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; } }
Ahora usaría esta clase de ayuda como esto:
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);
¡Es importante usar un Contexto de una Vista o Actividad, no el contexto de la Aplicación! Espero que resuelva su problema, o ayudar a otra persona. Y si alguien tiene una solución mejor y más limpia, me interesa saber también.