comment puis-je rendre le dessin sur un bouton plus petit? L'icône est trop grande, en fait plus haute que le bouton. Voici le code que j'utilise:
<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>
Le haut est à quoi il devrait ressembler, le bas à quoi il ressemble maintenant.
J'ai essayé cela mais aucune image n'est affichée. :-(
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);
Réponses:
Vous devez utiliser un ImageButton et spécifier l'image dans
android:src
, et définirandroid:scaletype
surfitXY
Définition de la mise à l'échelle dessinable dans le code
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
la source
drawable.setBounds(0, 0, drawable.getIntrinsicWidth()*0.5, drawable.getIntrinsicHeight()*0.5);
J'ai trouvé une solution XML très simple et efficace qui ne nécessite pas
ImageButton
Créez un fichier dessinable pour votre image comme ci-dessous et utilisez-le pour
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>
Vous pouvez définir la taille de l'image avec
android:width
etandroid:height
propriétés.De cette façon, vous pouvez au moins obtenir la même taille pour différents écrans.
L'inconvénient est que ce n'est pas exactement comme fitXY qui redimensionnerait la largeur de l'image pour s'adapter à X et redimensionnerait la hauteur de l'image en conséquence.
la source
android:drawableTop
j'ai ajouté le nouveau dessinable. Quelles que soient les valeurs de largeur / hauteur que j'ai définies, cela me montre celle par défaut.Les boutons ne redimensionnent pas leurs images internes.
Ma solution ne nécessite pas de manipulation de code.
Il utilise une mise en page avec TextView et ImageView.
L'arrière-plan de la mise en page doit avoir le dessin 3D rouge.
Vous devrez peut-être définir l' attribut android: scaleType xml.
Exemple:
<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>
BTW:
Bonne chance
la source
Utilisez un ScaleDrawable comme Abhinav l'a suggéré.
Le problème est que le dessinable ne s'affiche pas alors - c'est une sorte de bogue dans ScaleDrawables. vous devrez changer le "niveau" par programme. Cela devrait fonctionner pour chaque bouton:
// 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]);
la source
Mon DiplayScaleHelper, qui fonctionne parfaitement:
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()); } } } } }
la source
Vous pouvez faire appel
setBounds
aux dessinables "composés" pour modifier la taille de l'image.Essayez ce code pour dimensionner automatiquement le dessinable de votre bouton:
DroidUtils.scaleButtonDrawables((Button) findViewById(R.id.ButtonTest), 1.0);
défini par cette fonction:
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); } } } } } }
Sachez que cela peut ne pas être appelé dans
onCreate()
une activité, car la hauteur et la largeur du bouton ne sont pas (encore) disponibles ici. Appelez-leonWindowFocusChanged()
ou utilisez cette solution pour appeler la fonction.Édité:
La première incarnation de cette fonction n'a pas fonctionné correctement. Il a utilisé le code userSeven7s pour redimensionner l'image, mais le retour
ScaleDrawable.getDrawable()
ne semble pas fonctionner (ni le retourScaleDrawable
) pour moi.Le code modifié utilise
setBounds
pour fournir les limites de l'image. Android adapte l'image dans ces limites.la source
onCreate()
.Si vous souhaitez utiliser 1 image et l'afficher dans une taille différente, vous pouvez utiliser l'échelle dessinable ( http://developer.android.com/guide/topics/resources/drawable-resource.html#Scale ).
la source
Je le fais comme ci-dessous. Cela crée une image de taille 100x100 dans le bouton indépendamment de l'image d'entrée.
drawable.bounds = Rect(0,0,100,100) button.setCompoundDrawables(drawable, null, null, null)
Ne pas utiliser
ScaleDrawable
non plus. Ne pas utiliser abutton.setCompoundDrawablesRelativeWithIntrinsicBounds()
résolu mon problème, car cela semble utiliser des limites intrinsèques (taille de l'image source) au lieu des limites que vous venez de définir.la source
Vous pouvez utiliser des tableaux de tailles différentes qui sont utilisés avec différentes densités / tailles d'écran, etc. afin que votre image soit parfaite sur tous les appareils.
Voir ici: http://developer.android.com/guide/practices/screens_support.html#support
la source
Avez-vous essayé d' encapsuler votre image dans un ScaleDrawable , puis de l'utiliser dans votre bouton?
la source
ScaleDrawable
serait parfait, mais cela ne fonctionne tout simplement pas. Cela semble avoir quelque chose à voir avec les «niveaux». Plus d'informations ici (et quelques solutions de contournement qui sont loin d'être parfaites): stackoverflow.com/questions/5507539/…Voici la fonction que j'ai créée pour mettre à l'échelle les dessins vectoriels. Je l'ai utilisé pour définir TextView composé dessiné.
/** * 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; }
la source
En utilisant la fonction "IMPORTER PAR BATCH DRAWABLE", vous pouvez importer une taille personnalisée en fonction de vos besoins, exemple 20dp * 20dp
Maintenant, après l'importation, utilisez l'image drawable_image importée comme drawable_source pour votre bouton
C'est plus simple comme ça
la source
C'est parce que vous ne l'avez pas fait
setLevel
. après voussetLevel(1)
, il sera affiché comme vous le souhaitezla source
Utilisation de l'extension 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)
Je suggère de créer une fonction d'extension sur TextView ( Button l'étend ) pour une réutilisation facile.
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) }
la source
J'ai essayé les techniques de cet article mais je n'ai trouvé aucune d'entre elles aussi attrayante. Ma solution consistait à utiliser une vue d'image et une vue de texte et d'aligner la vue d'image en haut et en bas à la vue de texte. De cette façon, j'ai obtenu le résultat souhaité. Voici un code:
<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>
la source
J'ai créé une classe de boutons personnalisée pour y parvenir.
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>
Utilisation 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>
la source
Canvas
ingetResizedDrawable
et dessinez-vous dedans si vous n'allez rien faire avec? La fonction entière pourrait être réduite àdrawable.setBounds(0, 0, mWidth, mHeight)
.