如何将宽度设置为"填充父级"的android按钮中的图标和文本居中

jlo*_*nte 112 user-interface android button alignment android-layout

我想要一个带有图标+文本的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" />
Run Code Online (Sandbox Code Playgroud)

有关如何实现这一目标的任何建议?

Rod*_*dja 73

android:drawableLeft总是保持android:paddingLeft与左边界的距离.当按钮未设置为android:width ="wrap_content"时,它将始终挂在左侧!

使用Android 4.0(API级别14),您可以使用android:drawableStart属性在文本的开头放置一个drawable.我提出的唯一向后兼容的解决方案是使用ImageSpan创建一个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);
Run Code Online (Sandbox Code Playgroud)

在我的情况下,我还需要调整Button的android:gravity属性,使其看起来居中:

<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" />
Run Code Online (Sandbox Code Playgroud)

  • drawableStart不起作用.请参阅此主题:http://stackoverflow.com/questions/15350990/how-come-the-behavior-of-drawablestart-doesnt-match-the-android-documentation此外,似乎当您使用spannable设置文本时,风格被忽略了. (11认同)
  • drawableStart不起作用,它在API级别17中添加以支持rtl (11认同)

Sar*_*van 32

我知道我迟到了回答这个问题,但这对我有所帮助:

<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>
Run Code Online (Sandbox Code Playgroud)

我从这里找到了这个解决方案:Android UI挣扎:制作一个带有居中文本和图标的按钮

在此输入图像描述

  • 这个问题是按钮不是框架布局的宽度. (5认同)

pet*_*ejl 27

我使用LinearLayout而不是Button.我需要使用的OnClickListener也适用于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>
Run Code Online (Sandbox Code Playgroud)


Ank*_*pli 8

我最近碰到了同样的问题.试图找到一个更便宜的解决方案,所以想出了这个.

   <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>
Run Code Online (Sandbox Code Playgroud)

然后,只需调用OnClickListenerLinearLayout.

希望这可以帮助某人,因为它似乎是一个非常常见的问题.:)

  • 这是一个好主意,但却是一个糟糕的解决方案。您可以使用drawableLeft 属性仅使用一个TextView 来实现相同的效果。这使您能够查看文本左侧的可绘制对象。 (2认同)

Flo*_*wra 7

我通过左右添加填充来调整它,如下所示:

<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"
            />
Run Code Online (Sandbox Code Playgroud)

  • 你如何管理你的宽度是动态的?如果旋转屏幕,所有图标都不会居中,对吗?我实际上面临这个问题 (4认同)

Leo*_*der 7

以前的所有答案似乎都已过时

您可以使用MaterialButtonnow来设置图标的重力。

 <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" />
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

编辑:

要使用材料组件,您显然需要:

添加依赖项 implementation 'com.google.android.material:material:1.1.0-alpha10'(最新版本)

使您的主题扩展“材料组件”主题

<style name="AppTheme" parent="Theme.MaterialComponents.Light">
...
</style>
Run Code Online (Sandbox Code Playgroud)

如果您不能这样做,请从“材质桥”主题扩展它

<style name="AppTheme" parent="Theme.MaterialComponents.Light.Bridge">
...
</style>
Run Code Online (Sandbox Code Playgroud)

  • 您不必更改整个应用程序主题,只需在 MaterialButton 标签上使用 app:theme 即可仅将主题应用于按钮本身 (4认同)

Raj*_*jiv 6

您可以使用自定义按钮来测量和绘制自己以容纳左侧绘图.请在此处找到示例和用法

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);
}
}
Run Code Online (Sandbox Code Playgroud)

用法

<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" />
Run Code Online (Sandbox Code Playgroud)

  • 不太准确,但我接受了 (2认同)

Ren*_*tik 5

这是我 3 年前写的解决方案。按钮有文本和左图标,并且在框架中,这里是实际按钮,可以通过fill_parent 拉伸。我无法再次测试它,但当时它正在工作。可能 Button 不必使用,可以用 TextView 替换,但我现在不会测试它,它在这里不会改变太多功能。

<FrameLayout
    android:id="@+id/login_button_login"
    android:background="@drawable/apptheme_btn_default_holo_dark"
    android:layout_width="fill_parent"
    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>
Run Code Online (Sandbox Code Playgroud)


Ted*_*opp 1

如果你尝试 android:gravity="center_horizo​​ntal" 会发生什么?

  • 这不起作用。文本有点居中,但drawableLeft 粘在左侧。 (7认同)