Как центрировать значок и текст в кнопке Android с шириной, установленной на «заполнить родительский элемент» - PullRequest
107 голосов
/ 03 сентября 2010

Я хочу иметь кнопку Android с иконкой + текст в центре.Я использую атрибут drawableLeft для установки изображения, это хорошо работает, если кнопка имеет ширину "wrap_content", но мне нужно растянуть ее до максимальной ширины, поэтому я использую ширину "fill_parent".Это перемещает мой значок прямо слева от кнопки, и я хочу, чтобы значок и текст центрировались внутри кнопки.

Я попытался настроить заполнение, но это только позволяет дать фиксированное значение, так что это не то, что мне нужно.Мне нужно, чтобы значок + текст был выровнен по центру.

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

Какие-нибудь предложения о том, как мне этого добиться?

Ответы [ 27 ]

2 голосов
/ 28 февраля 2014

Вы можете создать собственный виджет:

Класс 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);
}

}

Компоновка 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>

Чтобы использовать этот пользовательский виджет:

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

Вы должны предоставить пространство имен для пользовательских атрибутов xmlns: ibutton = "http://schemas.android.com/apk/res/com.test.android.xxx", где com.test.android.xxx - корневой пакет приложения.

Просто поместите его ниже xmlns: android =" http://schemas.android.com/apk/res/android".

ПоследнееВам понадобятся пользовательские атрибуты в файле attrs.xml.

В файле 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>

Для лучшего позиционирования оберните пользовательскую кнопку внутри LinearLayout, если вы хотите избежать потенциальных проблем с позиционированием RelativeLayout.

Наслаждайтесь!

2 голосов
/ 21 марта 2018

Попробуйте использовать эту библиотеку

OmegaCenterIconButton

enter image description here

1 голос
/ 18 марта 2019

Все предыдущие ответы кажутся устаревшими

Теперь вы можете использовать MaterialButton, который позволяет устанавливать гравитацию значка.

 <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

1 голос
/ 29 февраля 2016

Я центрировал textView со значком, используя paddingLeft, и выровнял textView по left | centerVertical . и для небольшого промежутка между видом и значком я использовал 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" />
1 голос
/ 02 октября 2015

Вы можете поместить кнопку поверх 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 голос
/ 31 января 2015
<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>

Поместите FrameLayout в LinearLayout и установите ориентацию по горизонтали.

0 голосов
/ 13 января 2011

Что произойдет, если вы попробуете android: gravity = "center_horizontal"?

0 голосов
/ 04 октября 2011

Я думаю, что Android: gravity = "центр" должен работать

0 голосов
/ 16 марта 2018

Если вы используете одно из решений пользовательского представления , будьте осторожны, поскольку они часто терпят неудачу при длинном или многострочном тексте . Я переписал некоторые ответы, заменил onDraw() и понял, что это неверный путь.

0 голосов
/ 08 октября 2017

используйте это android:background="@drawable/ic_play_arrow_black_24dp"

просто установите фон для иконки, которую вы хотите центрировать

...