¿Cómo puedo reducir el dibujo de un botón?

¿Cómo puedo hacer que el dibujo de un botón sea más pequeño? El icono es demasiado grande, en realidad más alto que el botón. Este es el código que estoy usando:

 

La parte superior es cómo debería verse, cuanto más bajo se vea ahora.

La parte superior es cómo debería verse, cuanto más bajo se vea ahora.

Intenté esto pero no se muestra ninguna imagen. 🙁

  Resources res = getResources(); ScaleDrawable sd = new ScaleDrawable(res.getDrawable(R.drawable.s_vit), 0, 10f, 10f); Button btn = (Button) findViewById(R.id.ButtonTest); btn.setCompoundDrawables(sd.getDrawable(), null, null, null); 

Debe usar ImageButton y especificar la imagen en android:src , y configurar android:scaletype para fitXY


Ajuste escalado dibujable en el código

 Drawable drawable = getResources().getDrawable(R.drawable.s_vit); drawable.setBounds(0, 0, (int)(drawable.getIntrinsicWidth()*0.5), (int)(drawable.getIntrinsicHeight()*0.5)); ScaleDrawable sd = new ScaleDrawable(drawable, 0, scaleWidth, scaleHeight); Button btn = findViewbyId(R.id.yourbtnID); btn.setCompoundDrawables(sd.getDrawable(), null, null, null); //set drawableLeft for example 

He encontrado una solución XML muy simple y efectiva que no requiere ImageButton

Haga un archivo dibujable para su imagen como a continuación y android:drawableLeft para android:drawableLeft

     

Puede establecer el tamaño de la imagen con android:width y android:height properties.

De esta forma, al menos podrías obtener el mismo tamaño para diferentes pantallas.

El inconveniente es que no es exactamente como fitXY lo que escalaría el ancho de la imagen para ajustarse a X y escalar la altura de la imagen en consecuencia.

Los botones no cambian el tamaño de sus imágenes internas.

Mi solución no requiere manipulación de código.

Utiliza un diseño con TextView e ImageView.

El fondo del diseño debe tener el 3d dibujable rojo.

Es posible que necesite definir el atributo android: scaleType xml.

Ejemplo:

     

Por cierto:

  1. Contar con diferentes icons de resolución puede resultar en una IU no predecible (icono demasiado grande o demasiado pequeño)
  2. El texto en la vista de texto (incluidos los botones) no llena el componente. Este es un problema de Android y no sé cómo resolverlo.
  3. Puede usarlo como una inclusión.

Buena suerte

Mi DiplayScaleHelper, que funciona perfectamente:

 import android.content.Context; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.ScaleDrawable; import android.widget.Button; public class DisplayHelper { public static void scaleButtonDrawables(Button btn, double fitFactor) { Drawable[] drawables = btn.getCompoundDrawables(); for (int i = 0; i < drawables.length; i++) { if (drawables[i] != null) { if (drawables[i] instanceof ScaleDrawable) { drawables[i].setLevel(1); } drawables[i].setBounds(0, 0, (int) (drawables[i].getIntrinsicWidth() * fitFactor), (int) (drawables[i].getIntrinsicHeight() * fitFactor)); ScaleDrawable sd = new ScaleDrawable(drawables[i], 0, drawables[i].getIntrinsicWidth(), drawables[i].getIntrinsicHeight()); if(i == 0) { btn.setCompoundDrawables(sd.getDrawable(), drawables[1], drawables[2], drawables[3]); } else if(i == 1) { btn.setCompoundDrawables(drawables[0], sd.getDrawable(), drawables[2], drawables[3]); } else if(i == 2) { btn.setCompoundDrawables(drawables[0], drawables[1], sd.getDrawable(), drawables[3]); } else { btn.setCompoundDrawables(drawables[0], drawables[1], drawables[2], sd.getDrawable()); } } } } } 

Use un ScaleDrawable como sugirió Abhinav .

El problema es que el dibujable no se muestra en ese momento, es una especie de error en ScaleDrawables. necesitarás cambiar el “nivel” programáticamente. Esto debería funcionar para cada botón:

 // Fix level of existing drawables Drawable[] drawables = myButton.getCompoundDrawables(); for (Drawable d : drawables) if (d != null && d instanceof ScaleDrawable) d.setLevel(1); myButton.setCompoundDrawables(drawables[0], drawables[1], drawables[2], drawables[3]); 

Puede llamar a setBounds en los setBounds “compuestos” para modificar el tamaño de la imagen.

Pruebe este código para autoesificar el dibujo de su botón:

 DroidUtils.scaleButtonDrawables((Button) findViewById(R.id.ButtonTest), 1.0); 

definido por esta función:

 public final class DroidUtils { /** scale the Drawables of a button to "fit" * For left and right drawables: height is scaled * eg. with fitFactor 1 the image has max. the height of the button. * For top and bottom drawables: width is scaled: * With fitFactor 0.9 the image has max. 90% of the width of the button * */ public static void scaleButtonDrawables(Button btn, double fitFactor) { Drawable[] drawables = btn.getCompoundDrawables(); for (int i = 0; i < drawables.length; i++) { if (drawables[i] != null) { int imgWidth = drawables[i].getIntrinsicWidth(); int imgHeight = drawables[i].getIntrinsicHeight(); if ((imgHeight > 0) && (imgWidth > 0)) { //might be -1 float scale; if ((i == 0) || (i == 2)) { //left or right -> scale height scale = (float) (btn.getHeight() * fitFactor) / imgHeight; } else { //top or bottom -> scale width scale = (float) (btn.getWidth() * fitFactor) / imgWidth; } if (scale < 1.0) { Rect rect = drawables[i].getBounds(); int newWidth = (int)(imgWidth * scale); int newHeight = (int)(imgHeight * scale); rect.left = rect.left + (int)(0.5 * (imgWidth - newWidth)); rect.top = rect.top + (int)(0.5 * (imgHeight - newHeight)); rect.right = rect.left + newWidth; rect.bottom = rect.top + newHeight; drawables[i].setBounds(rect); } } } } } } 

Tenga en cuenta que esto no se puede onCreate() en onCreate() de una actividad, porque la altura y el ancho del botón no están (todavía) disponibles allí. Llame esto en onWindowFocusChanged() o use esta solución para llamar a la función.

Editado:

La primera encarnación de esta función no funcionó correctamente. Usó el código userSeven7s para escalar la imagen, pero devolver ScaleDrawable.getDrawable() no parece funcionar (ni retorna ScaleDrawable ) para mí.

El código modificado usa setBounds para proporcionar los límites de la imagen. Android se ajusta a la imagen en estos límites.

Si desea usar 1 imagen y mostrarla en diferentes tamaños, puede usar la escala dibujable ( http://developer.android.com/guide/topics/resources/drawable-resource.html#Scale ).

Puede usar diferentes tamaños de mallas que se usan con diferentes densidades / tamaños de pantalla, etc. para que su imagen se vea bien en todos los dispositivos.

Vea aquí: http://developer.android.com/guide/practices/screens_support.html#support

¿ Trataste de envolver tu imagen en un ScaleDrawable y luego usarla en tu botón?

Aquí la función que creé para escalar vectores se puede dibujar. Lo usé para establecer el compuesto de TextView dibujable.

 /** * Used to load vector drawable and set it's size to intrinsic values * * @param context Reference to {@link Context} * @param resId Vector image resource id * @param tint If not 0 - colour resource to tint the drawable with. * @param newWidth If not 0 then set the drawable's width to this value and scale * height accordingly. * @return On success a reference to a vector drawable */ @Nullable public static Drawable getVectorDrawable(@NonNull Context context, @DrawableRes int resId, @ColorRes int tint, float newWidth) { VectorDrawableCompat drawableCompat = VectorDrawableCompat.create(context.getResources(), resId, context.getTheme()); if (drawableCompat != null) { if (tint != 0) { drawableCompat.setTint(ResourcesCompat.getColor(context.getResources(), tint, context.getTheme())); } drawableCompat.setBounds(0, 0, drawableCompat.getIntrinsicWidth(), drawableCompat.getIntrinsicHeight()); if (newWidth != 0.0) { float scale = newWidth / drawableCompat.getIntrinsicWidth(); float height = scale * drawableCompat.getIntrinsicHeight(); ScaleDrawable scaledDrawable = new ScaleDrawable(drawableCompat, Gravity.CENTER, 1.0f, 1.0f); scaledDrawable.setBounds(0,0, (int) newWidth, (int) height); scaledDrawable.setLevel(10000); return scaledDrawable; } } return drawableCompat; } 
  • Con la función “IMPORTADOR DE BATCH DRAWABLE”, puede importar tamaños personalizados según su ejemplo de requisito 20dp * 20dp

    • Ahora, después de importar, usa la imagen dibujable importada como drawable_source para tu botón

    • Es más simple de esta manera enter image description here

Es porque no estableciste setLevel . después de establecer setLevel(1) , se mostrará como quieras

Hice una clase de botón personalizado para lograr esto.

CustomButton.java

 public class CustomButton extends android.support.v7.widget.AppCompatButton { private Drawable mDrawable; public CustomButton(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.CustomButton, 0, 0); try { float mWidth = a.getDimension(R.styleable.CustomButton_drawable_width, 0); float mHeight = a.getDimension(R.styleable.CustomButton_drawable_width, 0); Drawable[] drawables = this.getCompoundDrawables(); Drawable[] resizedDrawable = new Drawable[4]; for (int i = 0; i < drawables.length; i++) { if (drawables[i] != null) { mDrawable = drawables[i]; } resizedDrawable[i] = getResizedDrawable(drawables[i], mWidth, mHeight); } this.setCompoundDrawables(resizedDrawable[0], resizedDrawable[1], resizedDrawable[2], resizedDrawable[3]); } finally { a.recycle(); } } public Drawable getmDrawable() { return mDrawable; } private Drawable getResizedDrawable(Drawable drawable, float mWidth, float mHeight) { if (drawable == null) { return null; } try { Bitmap bitmap; bitmap = Bitmap.createBitmap((int)mWidth, (int)mHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); return drawable; } catch (OutOfMemoryError e) { // Handle the error return null; } } } 

attrs.xml

        

Uso en xml

    

Probé las técnicas de esta publicación, pero no encontré ninguna de ellas tan atractiva. Mi solución fue usar una vista de imagen y una vista de texto y alinear la vista superior e inferior de la imagen con la vista de texto. De esta manera obtuve el resultado deseado. Aquí hay un código: