web-dev-qa-db-fra.com

Comment centrer l'icône et le texte d'un bouton Android avec une largeur définie sur "Remplir le parent"

Je veux avoir un bouton Android avec icône + texte centré à l'intérieur. J'utilise l'attribut drawableLeft pour définir l'image. Cela fonctionne bien si le bouton a une largeur de "wrap_content", mais que je dois m'étirer à la largeur maximale, donc j'utilise width "fill_parent". Cela déplace mon icône directement à la gauche du bouton et je veux que l'icône et le texte soient centrés à l'intérieur du bouton. 

J'ai essayé de configurer le rembourrage mais cela ne permet que de donner une valeur fixe, donc ce n'est pas ce dont j'ai besoin. J'ai besoin que l'icône + le texte soit aligné au centre.

<Button 
    Android:id="@+id/startTelemoteButton" 
    Android:text="@string/start_telemote"
    Android:drawableLeft="@drawable/start"
    Android:paddingLeft="20dip"
    Android:paddingRight="20dip"            
    Android:width="fill_parent"
    Android:heigh="wrap_content" />

Des suggestions sur la façon dont je pourrais y parvenir? 

102
jloriente

Android: drawableLeft garde toujours Android: paddingLeft comme distance du bord gauche. Lorsque le bouton n'est pas défini sur Android: width = "wrap_content", il sera toujours bloqué à gauche!

Avec Android 4.0 (API de niveau 14), vous pouvez utiliser Android: drawableStart attribute pour placer un dessin au début du texte. La seule solution rétrocompatible que j'ai créée consiste à utiliser un ImageSpan pour créer un spannable texte + image:

Button button = (Button) findViewById(R.id.button);
Spannable buttonLabel = new SpannableString(" Button Text");
buttonLabel.setSpan(new ImageSpan(getApplicationContext(), R.drawable.icon,      
    ImageSpan.ALIGN_BOTTOM), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
button.setText(buttonLabel);

Dans mon cas, je devais également ajuster l'attribut Android: gravity du bouton pour qu'il apparaisse centré:

<Button
  Android:id="@+id/button"
  Android:layout_width="wrap_content"
  Android:layout_height="wrap_content"
  Android:minHeight="32dp"
  Android:minWidth="150dp"
  Android:gravity="center_horizontal|top" />
70
Rodja

Je sais que je suis en retard pour répondre à cette question, mais cela m'a aidé:

<FrameLayout
            Android:layout_width="match_parent"
            Android:layout_height="35dp"
            Android:layout_marginBottom="5dp"
            Android:layout_marginTop="10dp"
            Android:background="@color/fb" >

            <Button
                Android:id="@+id/fbLogin"
                Android:layout_width="wrap_content"
                Android:layout_height="match_parent"
                Android:layout_gravity="center"
                Android:background="@null"
                Android:drawableLeft="@drawable/ic_facebook"
                Android:gravity="center"
                Android:minHeight="0dp"
                Android:minWidth="0dp"
                Android:text="FACEBOOK"
                Android:textColor="@Android:color/white" />
        </FrameLayout>

J'ai trouvé cette solution à partir d'ici: L'interface utilisateur Android peine à créer un bouton avec un texte et une icône centrés

enter image description here

31
Sarvan

J'ai utilisé LinearLayout au lieu de Bouton . Le OnClickListener , que je dois utiliser fonctionne également pour LinearLayout.

<LinearLayout
    Android:id="@+id/my_button"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="@drawable/selector"
    Android:gravity="center"
    Android:orientation="horizontal"
    Android:clickable="true">

    <ImageView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_marginRight="15dp"
        Android:adjustViewBounds="true"
        Android:scaleType="fitCenter"
        Android:src="@drawable/icon" />

    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:gravity="center"
        Android:text="Text" />

</LinearLayout>
25
petrnohejl

Vous pouvez utiliser un bouton personnalisé qui mesure et dessine pour accueillir un dessinable à gauche. Veuillez trouver un exemple et une utilisation ici

public class DrawableAlignedButton extends Button {

    public DrawableAlignedButton(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public DrawableAlignedButton(Context context) {
    super(context);
}

public DrawableAlignedButton(Context context, AttributeSet attrs, int style) {
    super(context, attrs, style);
}

private Drawable mLeftDrawable;

@Override
    //Overriden to work only with a left drawable.
public void setCompoundDrawablesWithIntrinsicBounds(Drawable left,
        Drawable top, Drawable right, Drawable bottom) {
    if(left == null) return;
    left.setBounds(0, 0, left.getIntrinsicWidth(), left.getIntrinsicHeight());
    mLeftDrawable = left;
}

@Override
protected void onDraw(Canvas canvas) {
    //transform the canvas so we can draw both image and text at center.
    canvas.save();
    canvas.translate(2+mLeftDrawable.getIntrinsicWidth()/2, 0);
    super.onDraw(canvas);
    canvas.restore();
    canvas.save();
    int widthOfText = (int)getPaint().measureText(getText().toString());
    int left = (getWidth()+widthOfText)/2 - mLeftDrawable.getIntrinsicWidth() - 2;
    canvas.translate(left, (getHeight()-mLeftDrawable.getIntrinsicHeight())/2);
    mLeftDrawable.draw(canvas);
    canvas.restore();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int height = getMeasuredHeight();
    height = Math.max(height, mLeftDrawable.getIntrinsicHeight() + getPaddingTop() + getPaddingBottom());
    setMeasuredDimension(getMeasuredWidth(), height);
}
}

Usage

<com.mypackage.DrawableAlignedButton
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_weight="1"
        Android:drawableLeft="@drawable/my_drawable"
        Android:gravity="center"
        Android:padding="7dp"
        Android:text="My Text" />
6
Rajiv

Je suis récemment tombé sur le même problème. Essayé de trouver une solution moins chère alors proposé avec cela.

   <LinearLayout
        Android:id="@+id/linearButton"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:background="@drawable/selector_button_translucent_ab_color"
        Android:clickable="true"
        Android:descendantFocusability="blocksDescendants"
        Android:gravity="center"
        Android:orientation="horizontal" >

        <ImageView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:contentDescription="@string/app_name"
            Android:src="@drawable/ic_launcher" />

        <TextView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="@string/app_name"
            Android:textColor="@Android:color/white" />
    </LinearLayout>

Ensuite, appelez simplement OnClickListener sur LinearLayout.

J'espère que cela aide quelqu'un car cela semble être un problème très courant. :)

6
Ankit Popli

Je l’ajuste en ajoutant un rembourrage à gauche et à droite comme suit:

<Button
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_weight="1"
            Android:id="@+id/btn_facebookact_like"
            Android:text="@string/btn_facebookact_like"
            Android:textColor="@color/black"
            Android:textAllCaps="false"
            Android:background="@color/white"
            Android:drawableStart="@drawable/like"
            Android:drawableLeft="@drawable/like"
            Android:gravity="center"
            Android:layout_gravity="center"
            Android:paddingLeft="40dp"
            Android:paddingRight="40dp"
            />
5
Flowra

C'est ma solution ..

<FrameLayout
    Android:id="@+id/login_button_login"
    Android:background="@drawable/apptheme_btn_default_holo_dark"
    Android:layout_width="280dp"
    Android:layout_gravity="center"
    Android:layout_height="40dp">
    <Button
        Android:clickable="false"
        Android:drawablePadding="15dp"
        Android:layout_gravity="center"
        style="@style/WhiteText.Small.Bold"
        Android:drawableLeft="@drawable/lock"
        Android:background="@color/transparent"
        Android:text="LOGIN" />
</FrameLayout>
4
Renetik

Je sais que cette question est un peu plus ancienne, mais vous êtes peut-être toujours ouvert aux astuces ou solutions de contournement:

Créez un "wrap_content" RelativeLayout avec l'image du bouton comme arrière-plan ou le bouton lui-même comme premier élément de la présentation. Obtenez un LinearLayout et définissez-le sur "layout_centerInParent" et "wrap_content". Ensuite, définissez votre Drawable comme ImageView. Enfin, définissez un TextView avec votre texte (paramètres régionaux).

donc, fondamentalement, vous avez cette structure:

RelativeLayout
  Button
    LinearLayout
      ImageView
      TextView

ou comme ceci:

RelativeLayout with "Android-specific" button image as background
  LinearLayout
    ImageView
    TextView

Je sais qu'avec cette solution, il y a de nombreux éléments à traiter, mais vous pouvez très facilement créer votre propre bouton personnalisé et définir la position exacte du texte et des éléments dessinables :)

4
einschnaehkeee

Ma façon de le résoudre a consisté à entourer le bouton d’éléments <View ../> légers, redimensionnant de manière dynamique. Vous trouverez ci-dessous plusieurs exemples de ce qui peut être réalisé avec ceci:

 Demo by Dev-iL

Notez que la zone cliquable des boutons de l'exemple 3 est la même que celle de 2 (c'est-à-dire avec des espaces), ce qui diffère de l'exemple 4 dans lequel il n'y a pas d'espaces "non cliquables" entre les deux.

Code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical">
    <TextView
        Android:layout_marginStart="5dp"
        Android:layout_marginLeft="5dp"
        Android:layout_marginTop="10dp"
        Android:layout_marginBottom="5dp"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:textStyle="bold"
        Android:text="Example 1: Button with a background color:"/>
    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">
        <View
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"/>
        <Button
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Button"
            Android:textColor="@Android:color/white"
            Android:drawableLeft="@Android:drawable/ic_secure"
            Android:drawableStart="@Android:drawable/ic_secure"
            Android:background="@Android:color/darker_gray"
            Android:paddingStart="20dp"
            Android:paddingEnd="20dp"
            Android:layout_weight="0.3"/>
        <!-- Play around with the above 3 values to modify the clickable 
             area and image alignment with respect to text -->
        <View
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"/>
    </LinearLayout>

    <TextView
        Android:layout_marginStart="5dp"
        Android:layout_marginLeft="5dp"
        Android:layout_marginTop="20dp"
        Android:layout_marginBottom="5dp"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:textStyle="bold"
        Android:text="Example 2: Button group + transparent layout + spacers:"/>
    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">
        <View
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"/>
        <Button
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Button"
            Android:textColor="@Android:color/white"
            Android:drawableLeft="@Android:drawable/ic_secure"
            Android:drawableStart="@Android:drawable/ic_secure"
            Android:background="@Android:color/darker_gray"
            Android:paddingStart="10dp"
            Android:paddingEnd="10dp"
            Android:layout_weight="1"/>
        <View
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"/>
        <Button
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Button"
            Android:textColor="@Android:color/white"
            Android:drawableLeft="@Android:drawable/ic_secure"
            Android:drawableStart="@Android:drawable/ic_secure"
            Android:background="@Android:color/darker_gray"
            Android:paddingStart="10dp"
            Android:paddingEnd="10dp"
            Android:layout_weight="1"/>
        <View
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"/>
        <Button
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Button"
            Android:textColor="@Android:color/white"
            Android:drawableLeft="@Android:drawable/ic_secure"
            Android:drawableStart="@Android:drawable/ic_secure"
            Android:background="@Android:color/darker_gray"
            Android:paddingStart="10dp"
            Android:paddingEnd="10dp"
            Android:layout_weight="1"/>
        <View
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"/>
    </LinearLayout>

    <TextView
        Android:layout_marginStart="5dp"
        Android:layout_marginLeft="5dp"
        Android:layout_marginTop="20dp"
        Android:layout_marginBottom="5dp"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:textStyle="bold"
        Android:text="Example 3: Button group + colored layout:"/>
    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:background="@Android:color/darker_gray">
        <View
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"/>
        <Button
            style="?android:attr/buttonBarButtonStyle"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Button"
            Android:textColor="@Android:color/white"
            Android:drawableLeft="@Android:drawable/ic_secure"
            Android:drawableStart="@Android:drawable/ic_secure"
            Android:background="@Android:color/darker_gray"
            Android:paddingStart="10dp"
            Android:paddingEnd="10dp"
            Android:layout_weight="1"/>
        <View
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"/>
        <Button
            style="?android:attr/buttonBarButtonStyle"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Button"
            Android:textColor="@Android:color/white"
            Android:drawableLeft="@Android:drawable/ic_secure"
            Android:drawableStart="@Android:drawable/ic_secure"
            Android:background="@Android:color/darker_gray"
            Android:paddingStart="10dp"
            Android:paddingEnd="10dp"
            Android:layout_weight="1"/>
        <View
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"/>
        <Button
            style="?android:attr/buttonBarButtonStyle"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Button"
            Android:textColor="@Android:color/white"
            Android:drawableLeft="@Android:drawable/ic_secure"
            Android:drawableStart="@Android:drawable/ic_secure"
            Android:background="@Android:color/darker_gray"
            Android:paddingStart="10dp"
            Android:paddingEnd="10dp"
            Android:layout_weight="1"/>
        <View
            Android:layout_width="0dp"
            Android:layout_height="match_parent"
            Android:layout_weight="1"/>
    </LinearLayout>

    <TextView
        Android:layout_marginStart="5dp"
        Android:layout_marginLeft="5dp"
        Android:layout_marginTop="20dp"
        Android:layout_marginBottom="5dp"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:textStyle="bold"
        Android:text="Example 4 (reference): Button group + no spacers:"/>
    <LinearLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:background="@Android:color/darker_gray">
        <Button
            style="?android:attr/buttonBarButtonStyle"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Button"
            Android:textColor="@Android:color/white"
            Android:drawableLeft="@Android:drawable/ic_secure"
            Android:drawableStart="@Android:drawable/ic_secure"
            Android:background="@Android:color/darker_gray"
            Android:paddingStart="10dp"
            Android:paddingEnd="10dp"
            Android:layout_weight="1"/>
        <Button
            style="?android:attr/buttonBarButtonStyle"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Button"
            Android:textColor="@Android:color/white"
            Android:drawableLeft="@Android:drawable/ic_secure"
            Android:drawableStart="@Android:drawable/ic_secure"
            Android:background="@Android:color/darker_gray"
            Android:paddingStart="10dp"
            Android:paddingEnd="10dp"
            Android:layout_weight="1"/>
        <Button
            style="?android:attr/buttonBarButtonStyle"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="Button"
            Android:textColor="@Android:color/white"
            Android:drawableLeft="@Android:drawable/ic_secure"
            Android:drawableStart="@Android:drawable/ic_secure"
            Android:background="@Android:color/darker_gray"
            Android:paddingStart="10dp"
            Android:paddingEnd="10dp"
            Android:layout_weight="1"/>   
    </LinearLayout>
</LinearLayout>
3
Dev-iL

Vous pouvez créer un widget personnalisé:

La classe Java IButton:

public class IButton extends RelativeLayout {

private RelativeLayout layout;
private ImageView image;
private TextView text;

public IButton(Context context) {
    this(context, null);
}

public IButton(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public IButton(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.ibutton, this, true);

    layout = (RelativeLayout) view.findViewById(R.id.btn_layout);

    image = (ImageView) view.findViewById(R.id.btn_icon);
    text = (TextView) view.findViewById(R.id.btn_text);

    if (attrs != null) {
        TypedArray attributes = context.obtainStyledAttributes(attrs,R.styleable.IButtonStyle);

        Drawable drawable = attributes.getDrawable(R.styleable.IButtonStyle_button_icon);
        if(drawable != null) {
            image.setImageDrawable(drawable);
        }

        String str = attributes.getString(R.styleable.IButtonStyle_button_text);
        text.setText(str);

        attributes.recycle();
    }

}

@Override
public void setOnClickListener(final OnClickListener l) {
    super.setOnClickListener(l);
    layout.setOnClickListener(l);
}

public void setDrawable(int resId) {
    image.setImageResource(resId);
}

}

La mise en page ibutton.xml  

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/btn_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:clickable="true" >

<ImageView
    Android:id="@+id/btn_icon"
    Android:layout_width="wrap_content"
    Android:layout_height="fill_parent"
    Android:layout_marginRight="2dp"
    Android:layout_toLeftOf="@+id/btn_text"
    Android:duplicateParentState="true" />

<TextView
    Android:id="@+id/btn_text"
    Android:layout_width="wrap_content"
    Android:layout_height="fill_parent"
    Android:layout_centerInParent="true"
    Android:duplicateParentState="true"
    Android:gravity="center_vertical"
    Android:textColor="#000000" />
</RelativeLayout>

Pour utiliser ce widget personnalisé:

<com.test.Android.widgets.IButton
     Android:id="@+id/new"
     Android:layout_width="fill_parent"         
     Android:layout_height="@dimen/button_height"
     ibutton:button_text="@string/btn_new"
     ibutton:button_icon="@drawable/ic_action_new" />

Vous devez fournir l'espace de noms pour les attributs personnalisés Xmlns: ibutton = "http://schemas.Android.com/apk/res/com.test.Android.xxx" Où com. test.Android.xxx est le package racine de l'application.

Il suffit de le placer ci-dessous xmlns: Android = "http://schemas.Android.com/apk/res/Android".

La dernière chose dont vous aurez besoin sont les attributs personnalisés du fichier attrs.xml.

Dans le attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="IButtonStyle">
        <attr name="button_text" />
        <attr name="button_icon" format="integer" />
    </declare-styleable>

    <attr name="button_text" />

</resources>

Pour un meilleur positionnement, placez le bouton personnalisé dans un LinearLayout, si vous souhaitez éviter les problèmes potentiels liés au positionnement de RelativeLayout.

Prendre plaisir!

2
kirilv

Essayez d'utiliser cette bibliothèque 

OmegaCenterIconButton

 enter image description here

2
T. Roman

Avait un problème similaire, mais je voulais avoir un centre dessinable sans texte ni mise en page enveloppée. La solution consistait à créer un bouton personnalisé et à en ajouter un supplémentaire, en plus des options GAUCHE, DROITE, EN HAUT et EN BAS. On peut facilement modifier l’emplacement pouvant être dessiné et l’avoir dans la position souhaitée par rapport au texte.

CenterDrawableButton.Java

public class CenterDrawableButton extends Button {
    private Drawable mDrawableCenter;

    public CenterDrawableButton(Context context) {
        super(context);
        init(context, null);
    }

    public CenterDrawableButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public CenterDrawableButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    @TargetApi(Build.VERSION_CODES.Lollipop)
    public CenterDrawableButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }


    private void init(Context context, AttributeSet attrs){
        //if (isInEditMode()) return;
        if(attrs!=null){
            TypedArray a = context.getTheme().obtainStyledAttributes(
                    attrs, R.styleable.CenterDrawableButton, 0, 0);

            try {
                setCenterDrawable(a.getDrawable(R.styleable.CenterDrawableButton_drawableCenter));

            } finally {
                a.recycle();
            }

        }
    }

    public void setCenterDrawable(int center) {
        if(center==0){
            setCenterDrawable(null);
        }else
        setCenterDrawable(getContext().getResources().getDrawable(center));
    }
    public void setCenterDrawable(@Nullable Drawable center) {
        int[] state;
        state = getDrawableState();
        if (center != null) {
            center.setState(state);
            center.setBounds(0, 0, center.getIntrinsicWidth(), center.getIntrinsicHeight());
            center.setCallback(this);
        }
        mDrawableCenter = center;
        invalidate();
        requestLayout();
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        if(mDrawableCenter!=null) {
            setMeasuredDimension(Math.max(getMeasuredWidth(), mDrawableCenter.getIntrinsicWidth()),
                    Math.max(getMeasuredHeight(), mDrawableCenter.getIntrinsicHeight()));
        }
    }
    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        if (mDrawableCenter != null) {
            int[] state = getDrawableState();
            mDrawableCenter.setState(state);
            mDrawableCenter.setBounds(0, 0, mDrawableCenter.getIntrinsicWidth(),
                    mDrawableCenter.getIntrinsicHeight());
        }
        invalidate();
    }

    @Override
    protected void onDraw(@NonNull Canvas canvas) {
        super.onDraw(canvas);

        if (mDrawableCenter != null) {
            Rect rect = mDrawableCenter.getBounds();
            canvas.save();
            canvas.translate(getWidth() / 2 - rect.right / 2, getHeight() / 2 - rect.bottom / 2);
            mDrawableCenter.draw(canvas);
            canvas.restore();
        }
    }
}

attrs.xml

<resources>
    <attr name="drawableCenter" format="reference"/>
    <declare-styleable name="CenterDrawableButton">
        <attr name="drawableCenter"/>
    </declare-styleable>
</resources>

usage

<com.virtoos.Android.view.custom.CenterDrawableButton
            Android:id="@id/centerDrawableButton"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            app:drawableCenter="@Android:drawable/ic_menu_info_details"/>
2
Vilen

Vous pouvez mettre le bouton sur un LinearLayout

<RelativeLayout
        Android:layout_width="match_parent"
        Android:layout_height="@dimen/activity_login_fb_height"
        Android:background="@mipmap/bg_btn_fb">
        <LinearLayout
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:gravity="center">
            <TextView
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:id="@+id/lblLoginFb"
                Android:textColor="@color/white"
                Android:drawableLeft="@mipmap/icon_fb"
                Android:textSize="@dimen/activity_login_fb_textSize"
                Android:text="Login with Facebook"
                Android:gravity="center" />
        </LinearLayout>
        <Button
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:id="@+id/btnLoginFb"
            Android:background="@color/transparent"
            />
    </RelativeLayout>
1
butcher202
<style name="captionOnly">
    <item name="Android:background">@null</item>
    <item name="Android:clickable">false</item>
    <item name="Android:focusable">false</item>
    <item name="Android:minHeight">0dp</item>
    <item name="Android:minWidth">0dp</item>
</style>

<FrameLayout
   style="?android:attr/buttonStyle"
   Android:layout_width="match_parent"
   Android:layout_height="wrap_content" >

    <Button
       style="@style/captionOnly"
       Android:layout_width="wrap_content"
       Android:layout_height="wrap_content"
       Android:layout_gravity="center"
       Android:drawableLeft="@Android:drawable/ic_delete"
       Android:gravity="center"
       Android:text="Button Challenge" />
</FrameLayout>

Placez le FrameLayout dans LinearLayout et définissez l'orientation sur Horizontal.

1

Si vous utilisez l'une des solutions {vue personnalisée} _, soyez prudent, car elles échouent souvent sur le texte long ou multiligne . J'ai réécrit quelques réponses, remplacé onDraw() et compris que c'était une mauvaise façon.

0
CoolMind

Il s’agit peut-être d’un vieux fil de discussion/fermé, mais j’ai cherché partout, je n’ai trouvé rien d’utile, jusqu’à ce que je décide de créer ma propre solution. Si quelqu'un cherche une réponse, essayez celui-ci, cela vous évitera peut-être une minute de réflexion.

          <LinearLayout
            Android:id="@+id/llContainer"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:background="@drawable/selector"
            Android:clickable="true"
            Android:gravity="center"
            Android:orientation="vertical"
            Android:padding="10dp"
            Android:textStyle="bold">

            <TextView
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:gravity="center"
                Android:text="This is a text" />

            <ImageView
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:src="@drawable/icon_image />


        </LinearLayout>

Étant donné que la disposition linéaire agit en tant que conteneur et que celui qui possède le sélecteur, lorsque vous cliquez sur la disposition linéaire entière, cela ressemble à ce que cela devrait être. si vous voulez qu'il soit à la fois centré, utilisez insteaf relatif. Si vous voulez qu'il soit centré horizontalement, changez l'orientation en horizontal. 

Prenez note NE PAS oubliez pas d’ajouter Android: clickable = "true" dans votre conteneur principal (relatif ou linéaire) pour que l’action se déroule. 

Encore une fois, cela peut être un vieux fil, mais peut toujours aider quelqu'un là-bas.

-les cheers espèrent que cela aide - happycodings.

0
ralphgabb

Solution sale.

Android:paddingTop="10dp"
Android:drawableTop="@drawable/ic_src"

Trouver le bon rembourrage résout le problème. Cependant, pour des écrans variés, utilisez un remplissage différent et mettez-le dans la ressource dimens du dossier de valeurs respectif. 

0
Ngudup

Utilisez RelativeLayout (conteneur) et Android: layout_centerHorizontal = "true" , Mon exemple: 

                <RelativeLayout
                    Android:layout_width="0dp"
                    Android:layout_height="match_parent"
                    Android:layout_weight="1" >

                    <CheckBox
                        Android:layout_width="wrap_content"
                        Android:layout_height="match_parent"
                        Android:layout_centerHorizontal="true"
                        Android:layout_gravity="center"
                        Android:layout_marginBottom="5dp"
                        Android:layout_marginLeft="10dp"
                        Android:layout_marginTop="5dp"
                        Android:button="@drawable/bg_fav_detail"
                        Android:drawablePadding="5dp"
                        Android:text=" Favorite" />
                </RelativeLayout>
0
vuhung3990

classe publique DrawableCenterTextView extend TextView {

public DrawableCenterTextView(Context context, AttributeSet attrs,
        int defStyle) {
    super(context, attrs, defStyle);
}

public DrawableCenterTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public DrawableCenterTextView(Context context) {
    super(context);
}

@Override
protected void onDraw(Canvas canvas) {
    Drawable[] drawables = getCompoundDrawables();
    if (drawables != null) {
        Drawable drawableLeft = drawables[0];
        Drawable drawableRight = drawables[2];
        if (drawableLeft != null || drawableRight != null) {
            float textWidth = getPaint().measureText(getText().toString());
            int drawablePadding = getCompoundDrawablePadding();
            int drawableWidth = 0;
            if (drawableLeft != null)
                drawableWidth = drawableLeft.getIntrinsicWidth();
            else if (drawableRight != null) {
                drawableWidth = drawableRight.getIntrinsicWidth();
            }
            float bodyWidth = textWidth + drawableWidth + drawablePadding;
            canvas.translate((getWidth() - bodyWidth) / 2, 0);
        }
    }
    super.onDraw(canvas);
}

}

0
tangjun

Autre possibilité de garder le thème du bouton.

<Button
            Android:id="@+id/pf_bt_edit"
            Android:layout_height="@dimen/standard_height"
            Android:layout_width="match_parent"
            />

        <LinearLayout
            Android:layout_width="0dp"
            Android:layout_height="0dp"
            Android:layout_alignBottom="@id/pf_bt_edit"
            Android:layout_alignLeft="@id/pf_bt_edit"
            Android:layout_alignRight="@id/pf_bt_edit"
            Android:layout_alignTop="@id/pf_bt_edit"
            Android:layout_margin="@dimen/margin_10"
            Android:clickable="false"
            Android:elevation="20dp"
            Android:gravity="center"
            Android:orientation="horizontal"
            >

            <ImageView
                Android:layout_width="wrap_content"
                Android:layout_height="match_parent"
                Android:adjustViewBounds="true"
                Android:clickable="false"
                Android:src="@drawable/ic_edit_white_48dp"/>

            <TextView
                Android:id="@+id/pf_tv_edit"
                Android:layout_width="wrap_content"
                Android:layout_height="match_parent"
                Android:layout_marginLeft="@dimen/margin_5"
                Android:clickable="false"
                Android:gravity="center"
                Android:text="@string/pf_bt_edit"/>

        </LinearLayout>

Avec cette solution, si vous ajoutez @ Color/your_color @ Color/your_highlight_color dans votre thème d'activité, vous pouvez avoir le thème Matherial sur Lollipop avec ombre et ondulation, et pour la version précédente un bouton plat avec votre couleur et surligner la couleur lorsque vous appuyez dessus.

De plus, avec cette solution redimensionnement automatique de l'image

Résultat: Premier sur le périphérique Lollipop Second: Sur le périphérique pré-Lollipop 3ème: Bouton de pré-périphérique du Lollipop

 enter image description here

0
Anthone

Comme suggéré par Rodja, avant la version 4.0, il n'y avait pas de moyen direct de centrer le texte avec le dessin. Et en effet, définir une valeur padding_left éloigne le dessin de la bordure. Par conséquent, ma suggestion est que, au moment de l'exécution, vous calculiez exactement le nombre de pixels du bord gauche que votre dessinable doit être, puis transmettez-le à l'aide de setPadding Votre calcul peut ressembler à quelque chose comme:

int paddingLeft = (button.getWidth() - drawableWidth - textWidth) / 2;

La largeur de votre dessin est fixe et vous pouvez la rechercher et vous pouvez également calculer ou deviner la largeur du texte.

Enfin, vous devrez multiplier la valeur de remplissage par la densité de l’écran, ce que vous pouvez faire avec DisplayMetrics

0
ılǝ

Je ne le teste pas, mais il semble que vous puissiez utiliser Bibliothèque CenteredContentButton

0
Viacheslav

Je pense que Android: gravity = "center" devrait fonctionner

0
devanshu_kaushik

utiliser ce Android:background="@drawable/ic_play_arrow_black_24dp"

il suffit de définir l’arrière-plan sur l’icône que vous souhaitez centrer

0
kudzai zishumba

Toutes les réponses sont obsolètes !!!

Vous pouvez maintenant utiliser la MaterialButton qui permet de définir la gravité de l’icône.

 <com.google.Android.material.button.MaterialButton
        Android:id="@+id/btnDownloadPdf"
        Android:layout_width="0dp"
        Android:layout_height="56dp"
        Android:layout_margin="16dp"
        Android:gravity="center"
        Android:textAllCaps="true"
        app:backgroundTint="#fc0"
        app:icon="@drawable/ic_pdf"
        app:iconGravity="textStart"
        app:iconPadding="10dp"
        app:iconTint="#f00"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        tools:text="Download Pdf" />

 enter image description here 

0
Leo Droidcoder

Que se passe-t-il si vous essayez Android: gravity = "center_horizontal"?

0
Ted Hopp

J'ai centré textView avec l'icône en utilisant paddingLeft et en alignant textView sur left | centerVertical . et pour un petit espace entre la vue et l'icône, j'ai utilisé drawablePadding

         <Button
            Android:id="@+id/have_it_main"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:background="@drawable/textbox"
            Android:drawableLeft="@drawable/have_it"
            Android:drawablePadding="30dp"
            Android:gravity="left|center_vertical"
            Android:paddingLeft="60dp"
            Android:text="Owner Contact"
            Android:textColor="@Android:color/white" />
0
Xar E Ahmer