¿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:
<Button
android:background="@drawable/red_button"
android:drawableLeft="@drawable/s_vit"
android:id="@+id/ButtonTest"
android:gravity="left|center_vertical"
android:text="S-SERIES CALCULATOR"
android:textColor="@android:color/white"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:drawablePadding="10dp">
</Button>
La parte superior es como debería verse, la inferior como se ve 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);
Respuestas:
Debe usar un ImageButton y especificar la imagen en
android:src
, y establecerlaandroid:scaletype
enfitXY
Configuración de dibujable escalado en 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
fuente
drawable.setBounds(0, 0, drawable.getIntrinsicWidth()*0.5, drawable.getIntrinsicHeight()*0.5);
Encontré una solución XML muy simple y efectiva que no requiere
ImageButton
Haga un archivo dibujable para su imagen como se muestra a continuación y utilícelo para
android:drawableLeft
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/half_overlay" android:drawable="@drawable/myDrawable" android:width="40dp" android:height="40dp" /> </layer-list>
Puede establecer el tamaño de la imagen con
android:width
yandroid:height
propiedades.De esta manera, al menos podría obtener el mismo tamaño para diferentes pantallas.
El inconveniente es que no es exactamente como fitXY, que escalaría el ancho de la imagen para ajustarse a X y escalaría la altura de la imagen en consecuencia.
fuente
android:drawableTop
agregué el nuevo dibujo. No importa qué valores para el ancho / alto establezca, me muestra el predeterminado.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 dibujo 3d rojo.
Es posible que deba definir el atributo xml android: scaleType .
Ejemplo:
<LinearLayout android:id="@+id/list_item" android:layout_width="fill_parent" android:layout_height="50dp" android:padding="2dp" > <ImageView android:layout_width="50dp" android:layout_height="fill_parent" android:src="@drawable/camera" /> <TextView android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" android:lines="1" android:gravity="center_vertical" android:text="Hello - primary" /> </LinearLayout>
Por cierto:
Buena suerte
fuente
Usa un ScaleDrawable como Abhinav sugirió .
El problema es que el dibujable no se muestra entonces, es una especie de error en ScaleDrawables. deberá cambiar el "nivel" mediante programación. Esto debería funcionar para todos los botones:
// 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]);
fuente
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()); } } } } }
fuente
Puede recurrir
setBounds
a los elementos de diseño "compuestos" para modificar el tamaño de la imagen.Pruebe este código para ajustar automáticamente el tamaño del elemento de diseño 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 es posible que esto no se llame en
onCreate()
una actividad, porque la altura y el ancho del botón no están (todavía) disponibles allí. Llame a estoonWindowFocusChanged()
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 regresar
ScaleDrawable.getDrawable()
no parece funcionar (tampoco regresaScaleDrawable
) para mí.El código modificado se utiliza
setBounds
para proporcionar los límites de la imagen. Android encaja la imagen en estos límites.fuente
onCreate()
.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 ).
fuente
Lo estoy haciendo como se muestra a continuación. Esto crea una imagen de tamaño 100x100 en el botón independiente de la imagen de entrada.
drawable.bounds = Rect(0,0,100,100) button.setCompoundDrawables(drawable, null, null, null)
Sin usar
ScaleDrawable
ninguno. No usarbutton.setCompoundDrawablesRelativeWithIntrinsicBounds()
resolvió mi problema, ya que parece usar límites intrínsecos (tamaño de la imagen de origen) en lugar de los límites que acaba de establecer.fuente
Puede utilizar elementos de diseño de diferentes tamaños que se utilizan 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
fuente
¿Intentaste envolver tu imagen en un ScaleDrawable y luego usarlo en tu botón?
fuente
ScaleDrawable
sería perfecto, pero simplemente no funciona. Parece tener algo que ver con los "niveles". Más información aquí (y algunas soluciones que no son perfectas): stackoverflow.com/questions/5507539/…Aquí la función que creé para escalar elementos de diseño vectoriales. Lo usé para configurar TextView compuesto 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; }
fuente
Con la función "IMPORTACIÓN POR LOTES DIBUJABLE", puede importar un tamaño personalizado según su requisito, ejemplo 20dp * 20dp
Ahora, después de importar, use la imagen de dibujo importada como fuente de dibujo para su botón
Es más simple de esta manera
fuente
Es porque no lo hiciste
setLevel
. después de tisetLevel(1)
, se mostrará como quierasfuente
Usando la extensión de Kotlin
val drawable = ContextCompat.getDrawable(context, R.drawable.my_icon) // or resources.getDrawable(R.drawable.my_icon, theme) val sizePx = 25 drawable?.setBounds(0, 0, sizePx, sizePx) // (left, top, right, bottom) my_button.setCompoundDrawables(drawable, null, null, null)
Sugiero crear una función de extensión en TextView ( Button la extiende ) para una fácil reutilización.
button.leftDrawable(R.drawable.my_icon, 25) // Button extends TextView fun TextView.leftDrawable(@DrawableRes id: Int = 0, @DimenRes sizeRes: Int) { val drawable = ContextCompat.getDrawable(context, id) val size = context.resources.getDimensionPixelSize(sizeRes) drawable?.setBounds(0, 0, size, size) this.setCompoundDrawables(drawable, null, null, null) }
fuente
Probé las técnicas de esta publicación, pero ninguna de ellas me pareció tan atractiva. Mi solución fue usar una vista de imagen y una vista de texto y alinear la vista de imagen superior e inferior con la vista de texto. De esta manera obtuve el resultado deseado. Aquí hay un código:
<RelativeLayout android:id="@+id/relativeLayout1" android:layout_width="match_parent" android:layout_height="48dp" > <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignTop="@+id/textViewTitle" android:layout_alignBottom="@+id/textViewTitle" android:src="@drawable/ic_back" /> <TextView android:id="@+id/textViewBack" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/textViewTitle" android:layout_alignBottom="@+id/textViewTitle" android:layout_toRightOf="@+id/imageView1" android:text="Back" android:textColor="@color/app_red" android:textSize="@dimen/title_size" /> </RelativeLayout>
fuente
Hice una clase de botones personalizados 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
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CustomButton"> <attr name="drawable_width" format="dimension" /> <attr name="drawable_height" format="dimension" /> </declare-styleable> </resources>
Uso en xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:custom="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.MainActivity"> <com.example.CustomButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableTop="@drawable/ic_hero" android:text="Avenger" custom:drawable_height="10dp" custom:drawable_width="10dp" /> </RelativeLayout>
fuente
Canvas
engetResizedDrawable
y dibuja en ella si no se va a hacer nada con ella? Toda la función podría reducirse solo adrawable.setBounds(0, 0, mWidth, mHeight)
.