ti-enxame.com

Como centralizar ícone e texto em um botão Android com largura definida como "preenchimento pai"

Eu quero ter um botão Android com o ícone + texto centralizado dentro dele. Eu estou usando o atributo drawableLeft para definir a imagem, isso funciona bem se o botão tem uma largura de "wrap_content" mas eu preciso esticar a largura máxima, então eu uso largura "fill_parent". Isso move meu ícone para a direita do botão e quero que o ícone e o texto estejam centralizados dentro do botão. 

Eu tentei configurar o preenchimento, mas isso só permite dar um valor fixo, então não é o que eu preciso. Eu preciso ter o ícone + texto alinhado no centro.

<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" />

Alguma sugestão sobre como eu poderia conseguir isso? 

102
jloriente

Android: drawableLeft está sempre mantendo o Android: paddingLeft como uma distância da borda esquerda. Quando o botão não estiver definido para Android: width = "wrap_content", ele sempre ficará suspenso à esquerda!

Com o Android 4.0 (API level 14) você pode usar Android: drawableStart attribute para colocar um drawable no início do texto. A única solução compatível com versões anteriores que eu criei é usando um ImageSpan para criar um Text + Image Spannable:

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

No meu caso eu precisava também ajustar o atributo Android: gravidade do botão para fazer com que parecesse centrado:

<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

Eu sei que estou atrasado em responder a esta pergunta, mas isso me ajudou:

<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>

Eu encontrei esta solução a partir daqui: Android UI se esforça: fazendo um botão com o texto centralizado e ícone

enter image description here

31
Sarvan

Eu usei LinearLayout em vez de Button . O OnClickListener , que eu preciso usar funciona bem também para o 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

Você pode usar um botão personalizado que mede e desenha para acomodar um drawable à esquerda. Por favor, encontrar exemplo e uso aqui

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);
}
}

Uso

<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

Eu recentemente esbarrei no mesmo problema. Tentei encontrar uma solução mais barata assim surgiu com isso.

   <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>

Depois é só ligar para OnClickListener em LinearLayout.

Espero que isso ajude alguém como parece ser um problema muito comum. :)

6
Ankit Popli

Eu ajustei adicionando padding esquerda e direita da seguinte forma:

<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

Esta é a minha solução.

<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

Eu sei que esta questão é um pouco mais antiga, mas talvez você ainda esteja aberto para dicas ou soluções alternativas:

Crie um RelativeLayout "wrap_content" com a imagem do botão como fundo ou o próprio botão como o primeiro elemento do layout. Obtenha um LinearLayout e defina-o como "layout_centerInParent" e "wrap_content". Em seguida, defina seu Drawable como um Imageview. Por fim, defina um TextView com seu texto (localidade).

então basicamente você tem essa estrutura:

RelativeLayout
  Button
    LinearLayout
      ImageView
      TextView

ou assim:

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

Eu sei que com esta solução há muitos elementos para lidar, mas você pode criar muito fácil seu próprio botão personalizado com ele e também definir a posição exata de texto e drawables :)

4
einschnaehkeee

Minha maneira de resolver envolveu cercar o botão com elementos <View ../> leves que são redimensionados dinamicamente. Abaixo estão vários exemplos do que pode ser alcançado com isso:

Demo by Dev-iL

Observe que a área clicável dos botões no exemplo 3 é a mesma que em 2 (ou seja, com espaços), que é diferente do exemplo 4, onde não há intervalos "não clicáveis" entre eles.

Código:

<?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

Você pode criar um widget personalizado:

A 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);
}

}

O layout 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>

Para usar este widget personalizado:

<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" />

Você precisa fornecer o namespace para os atributos personalizados Xmlns: ibutton = "http://schemas.Android.com/apk/res/com.test.Android.xxx" onde com.test.Android.xxx é o pacote raiz do aplicativo.

Basta colocá-lo abaixo de xmlns: Android = "http://schemas.Android.com/apk/res/Android".

A última coisa que você vai precisar são os atributos personalizados no attrs.xml.

no 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>

Para melhor posicionamento, envolva o botão personalizado dentro de um LinearLayout, se você quiser evitar possíveis problemas com os posicionamentos do RelativeLayout.

Apreciar!

2
kirilv

Tente usar esta biblioteca 

OmegaCenterIconButton

enter image description here

2
T. Roman

Tinha problema semelhante, mas queria ter centro drawable sem texto e sem layouts envolvidos. A solução foi criar um botão personalizado e adicionar mais um drawable além de LEFT, RIGHT, TOP, BOTTOM. Pode-se facilmente modificar o posicionamento drawable e colocá-lo na posição desejada em relação ao texto.

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>

uso

<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

Você poderia colocar o botão sobre um 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>

Coloque o FrameLayout no LinearLayout e defina a orientação como Horizontal.

1
Feay Jarana Manotumruksa

Se você usar uma das soluções visão customizada, tenha cuidado, porque elas geralmente falham em texto longo ou multilinha . Eu reescrevi algumas respostas, substitui onDraw() e entendi que era um jeito errado.

0
CoolMind

Isso pode ser um segmento antigo/fechado, mas eu procurei em todos os lugares não encontrei algo útil, até que decidi criar minha própria solução. Se alguém aqui tentar procurar uma resposta, tente um minuto para pensar

          <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>

Como o layout Linear age como o contêiner e o que tem o seletor, quando você clica no layout linear inteiro, ele fica exatamente como deveria. Se você quiser que ele seja centralizado, use insteaf relativo. Se você quiser centralizado horizontalmente, mude a orientação para horizontal. 

Tome nota NÃO esqueça de adicionar Android: clickable = "true" ao seu container principal (relativo ou linear) para que a ação ocorra. 

Novamente, isso pode ser uma discussão antiga, mas ainda pode ajudar alguém.

-cheers espero que ajude - happycodings.

0
ralphgabb

Correção suja.

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

Descobrir o preenchimento correto resolve o propósito. No entanto, para tela variada, use padding diferente e coloque isso em recurso dimens na pasta de valores respectivos. 

0
Ngudup

Use RelativeLayout (container) e Android: layout_centerHorizontal = "true" , Minha amostra: 

                <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 pública DrawableCenterTextView estende 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

Outra possibilidade para manter o tema Button.

<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>

Com esta solução, se você adicionar @ Color/your_color @ Color/your_highlight_color No tema da sua atividade, poderá ter o tema Matherial no Lollipop com sombra e ondulação e na versão anterior botão liso com sua cor e destaque coor quando você pressiona.

Além disso, com esta solução autoresize de imagem

Resultado: Primeiro no dispositivo Lollipop Segundo: No dispositivo pré-pirulito 3º: Pré-pirulito pressione o botão

enter image description here

0
Anthone

Como sugerido por Rodja, antes da versão 4.0, não há uma maneira direta de centralizar o texto com o drawable. E, de fato, definir um valor padding_left move o drawable para longe da borda. Portanto, minha sugestão é que, em tempo de execução, você calcule exatamente quantos pixels da borda esquerda seu drawable precisa ser e, em seguida, passá-lo usando setPadding Seu cálculo pode ser algo como

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

A largura do seu drawable é fixo e você pode procurá-lo e você também pode calcular ou adivinhar a largura do texto.

Finalmente, você precisaria multiplicar o valor de preenchimento pela densidade da tela, o que você pode fazer usando DisplayMetrics

0
ılǝ

Eu não testei, mas parece que você pode usar CenteredContentButton library

0
Viacheslav

Eu acho que o Android: gravidade = "center" deve funcionar

0
devanshu_kaushik

use isso Android:background="@drawable/ic_play_arrow_black_24dp"

basta definir o plano de fundo para o ícone que você deseja centralizar

0
kudzai zishumba

Todas as respostas estão desatualizadas !!!

Você pode usar o MaterialButton agora que permite definir a gravidade do ícone.

 <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

O que acontece se você tentar Android: gravidade = "center_horizontal"?

0
Ted Hopp

Eu centralizei textView com o ícone usando paddingLeft e alinhei textView para left | centerVertical . e por um pequeno intervalo entre a visualização e o ícone eu usei 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