web-dev-qa-db-fra.com

Comment puis-je réduire le dessin sur un bouton?

comment puis-je rendre le dessin sur un bouton plus petit? L'icône est trop grande, plus haute que le bouton. C'est 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>

La partie supérieure correspond à l'apparence souhaitée, la partie inférieure à la présentation actuelle.

The upper is how it should look, the lower how it looks right now.

J'ai essayé cela mais aucune image ne s'affiche. :-(

    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);
77
Reto

Vous devez utiliser un ImageButton et spécifier l'image dans Android:src et définir Android:scaletype sur fitXY


Paramètre mis à l'échelle pouvant être dessiné en 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
67
Ronnie

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 les propriétés Android:width et Android:height.

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 redimensionne la largeur de l'image pour l'adapter à X et redimensionne la hauteur de l'image en conséquence.

79
Buddy

Les boutons ne redimensionnent pas leurs images intérieures.

Ma solution ne nécessite pas de manipulation de code.

Il utilise une mise en page avec TextView et ImageView.

Le fond de la mise en page doit avoir le 3d rouge dessinable.

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:

  1. Compter sur différentes icônes de résolution peut générer une interface utilisateur non prévisible (icône trop grande ou trop petite)
  2. Le texte dans la vue texte (y compris les boutons) ne remplit pas le composant. Ceci est un problème Android et je ne sais pas comment le résoudre.
  3. Vous pouvez l'utiliser comme un inclus.

Bonne chance

10
AlikElzin-kilaka

Mon DiplayScaleHelper, cela 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());
                }
            }
        }
    }
}
6
Vladimir

Utilisez un ScaleDrawable as Abhinav suggéré.

Le problème est que le dessin ne montre pas alors - c'est une sorte de bug dans ScaleDrawables. vous devrez changer le "niveau" par programmation. 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]);
5
zeh

Vous pouvez appeler setBounds sur les tiroirs "composés" pour modifier la taille de l'image. 

Essayez ce code pour redimensionner automatiquement le dessin 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 ne peut pas être appelé dans onCreate() d'une activité, car la hauteur et la largeur des boutons ne sont pas (encore) disponibles. Appelez ceci sur onWindowFocusChanged() 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 renvoyer ScaleDrawable.getDrawable()ne semble pas fonctionner (ne renvoie pas non plus ScaleDrawable).

Le code modifié utilise setBounds pour fournir les limites de l'image. Android correspond à l'image dans ces limites.

4
yonojoy

Si vous souhaitez utiliser une image et l'afficher dans une taille différente, vous pouvez utiliser une échelle dessinable ( http://developer.Android.com/guide/topics/resources/drawable-resource.html#Scale ).

1
kingori

Avez-vous essayé d’envelopper votre image dans ScaleDrawable puis de l’utiliser dans votre bouton?

0
Abhinav

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 button.setCompoundDrawablesRelativeWithIntrinsicBounds() a 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.

0
L P

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>
0
Jeffy Lee
  • À l'aide de la fonction "IMPORT DRAWABLE IMPORT", vous pouvez importer un format personnalisé en fonction de vos besoins

    • Maintenant, après l’importation, utilisez drawable_image importée comme drawable_source pour votre bouton.

    • C'est plus simple de cette façon  enter image description here

0
Santhosh PR

Voici la fonction que j'ai créée pour la mise à l'échelle de vecteurs dessinables. Je l'ai utilisé pour configurer TextView compoundable.

/**
 * 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;
}
0
zmicer

Vous pouvez utiliser différentes tailles de dessinables qui sont utilisées avec différentes densités/tailles d’écran, etc., afin que votre image corresponde bien à tous les appareils.

Voir ici: http://developer.Android.com/guide/practices/screens_support.html#support

0
HXCaine

C'est parce que vous n'avez pas setLevel. après vous setLevel(1), il sera affiché comme vous voulez

0
Songtao Lou