如何在按钮中拥有图像和文本中心

时间:2011-01-27 14:18:19

标签: android

我想在按钮上显示TEXTIcon

+----------------------------+
|          Icon TEXT         |
+----------------------------+

我试过

<Button 
      android:id="@+id/Button01" 
      android:layout_width="fill_parent"
      android:layout_height="wrap_content" 
      android:paddingLeft="40dip"
      android:text="TEXT"
      android:drawableLeft="@drawable/Icon" />

TextIcon不在中心位置 根据文字大小Text,我的Icon尺寸会有所不同,而Text应调整到中心位置。

我该怎么办?

13 个答案:

答案 0 :(得分:33)

你可以通过制作更复杂的布局来伪造它,但我不确定它是否值得。这是我一起入侵的东西:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
<Button
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:layout_alignTop="@+id/foreground"
    android:layout_alignBottom="@id/foreground"
    android:layout_alignRight="@id/foreground"
    android:layout_alignLeft="@id/foreground"
    android:onClick="clickedMe" />
   <RelativeLayout
        android:id="@id/foreground"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
    <TextView  
        android:id="@+id/button_text"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" 
        android:text="@string/hello" />
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_toLeftOf="@id/button_text"
        android:paddingTop="10dip"
        android:paddingBottom="10dip"
        android:src="@drawable/icon" />
</RelativeLayout>
</RelativeLayout>

可能有更简洁的方法来做到这一点。我倾向于让RelativeLayout有时候做我想做的事情。请注意,您需要注意z顺序(Button需要首先出现在顶级RelativeLayout中),您可能需要调整填充以使其看起来像您想要的那样。

答案 1 :(得分:29)

与其他一些方法类似,我认为一个好的解决方案是扩展Button并通过覆盖其onLayout方法添加缺少的功能:

public class CenteredIconButton extends Button {
    private static final int LEFT = 0, TOP = 1, RIGHT = 2, BOTTOM = 3;

    // Pre-allocate objects for layout measuring
    private Rect textBounds = new Rect();
    private Rect drawableBounds = new Rect();

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

    public CenteredIconButton(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.buttonStyle);
    }

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

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        if (!changed) return;

        final CharSequence text = getText();
        if (!TextUtils.isEmpty(text)) {
            TextPaint textPaint = getPaint();
            textPaint.getTextBounds(text.toString(), 0, text.length(), textBounds);
        } else {
            textBounds.setEmpty();
        }

        final int width = getWidth() - (getPaddingLeft() + getPaddingRight());

        final Drawable[] drawables = getCompoundDrawables();

        if (drawables[LEFT] != null) {
            drawables[LEFT].copyBounds(drawableBounds);
            int leftOffset =
                    (width - (textBounds.width() + drawableBounds.width()) + getRightPaddingOffset()) / 2 - getCompoundDrawablePadding();
            drawableBounds.offset(leftOffset, 0);
            drawables[LEFT].setBounds(drawableBounds);
        }

        if (drawables[RIGHT] != null) {
            drawables[RIGHT].copyBounds(drawableBounds);
            int rightOffset =
                    ((textBounds.width() + drawableBounds.width()) - width + getLeftPaddingOffset()) / 2 + getCompoundDrawablePadding();
            drawableBounds.offset(rightOffset, 0);
            drawables[RIGHT].setBounds(drawableBounds);
        }
    }
}

该样本仅适用于左侧和右侧drawable,但也可以扩展以调整顶部和底部drawables。

答案 2 :(得分:17)

这个怎么样?

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/lovely_color"
    android:clickable="true"
    android:onClick="clickHandler">

       <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="no?"
            android:textColor="@color/white"
            android:layout_centerHorizontal="true"
            android:drawableLeft="@drawable/lovely_icon"
            android:drawablePadding="10dp"
            android:padding="10dp"
            android:gravity="center"
            android:textSize="21sp"/>

</RelativeLayout>

答案 3 :(得分:5)

这应该有效

<LinearLayout        

android:layout_width="fill_parent"        
android:layout_height="wrap_content" 
android:gravity="center_horizontal">    
<TextView          
    android:id="@+id/button_text"        
    android:layout_width="wrap_content"         
    android:layout_height="wrap_content"        
    android:layout_centerInParent="true"        
     android:text="hello" />    
 <ImageView        
     android:layout_width="wrap_content"        
     android:layout_height="wrap_content"
     android:paddingBottom="10dip"
/>
</LinearLayout>

答案 4 :(得分:4)

如何使用SpannableString作为ImageSpan的文本?

Button myButton = ...
SpannableString ss = new SpannableString(" " + getString(R.string.my_button_text));
Drawable d = getResources().getDrawable(R.drawable.myIcon);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
ImageSpan span = new ImageSpan(d, DynamicDrawableSpan.ALIGN_BOTTOM);
ss.setSpan(span, 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
myButton.setText(ss);

答案 5 :(得分:1)

您可以根据按钮大小和图像大小设置填充:

Button button1 = null;
//initialize button….
ViewGroup.LayoutParams params = button1.getLayoutParams();
int btn1Width = ((int) (0.33 * (double)ecranWidth));
params.width = btn1Width;
button1.setLayoutParams(params);
button1.setPadding((btn1Width/2-9), 0, 0, 0);
//where (btn1Width/2-9)   =   size of button divided on 2 minux half size of icon… 

答案 6 :(得分:1)

简单的方法(尽管不完美)是将 paddingRight 设置为与图标相同的宽度。

答案 7 :(得分:0)

这就是我做的......它可以改进。文本居中,图标位于左侧。所以他们都没有集中在一起。

public class CustomButton extends Button
{
    Rect r = new Rect();
    private Drawable buttonIcon = null;
    private int textImageSeparation = 10;

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

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

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

    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);


        Drawable icon = getButtonIcon();
        if(icon != null)
        {
            int drawableHeight = icon.getIntrinsicHeight();
            int drawableWidth = icon.getIntrinsicWidth();
            if(icon instanceof BitmapDrawable)
            {
                Bitmap bitmap = ((BitmapDrawable)icon).getBitmap();
                drawableWidth = (int) AndroidScreenUtils.dipToPixels(bitmap.getWidth());
                drawableHeight = (int) AndroidScreenUtils.dipToPixels(bitmap.getHeight());
            }
            else
            {
                drawableWidth = (int) AndroidScreenUtils.dipToPixels(icon.getIntrinsicWidth());
                drawableHeight = (int) AndroidScreenUtils.dipToPixels(icon.getIntrinsicHeight());
            }
            float textWidth = getLayout().getPaint().measureText(getText().toString());
            float left = ((getWidth() - textWidth) / 2) - getTextImageSeparation() - drawableWidth;

            int height = getHeight();
            int top = (height - drawableHeight) /2;
            int right = (int) (left + drawableWidth);
            int bottom = top + drawableHeight;
            r.set((int) left, top, right, bottom);
            icon.setBounds(r);
            icon.draw(canvas);
        }
    }

    private Drawable getButtonIcon()
    {
        return buttonIcon;
    }

    public void setButtonIcon(Drawable buttonIcon)
    {
        this.buttonIcon = buttonIcon;
    }

    private int getTextImageSeparation()
    {
        return textImageSeparation;
    }

    public void setTextImageSeparation(int dips)
    {
        this.textImageSeparation = (int) AndroidScreenUtils.dipToPixels(dips);
    }



}

答案 8 :(得分:0)

{{1}}

答案 9 :(得分:0)

我制作了一个自定义组件来解决此问题。

组件类:

class CustomImageButton @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
    defStyleRes: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr, defStyleRes) {

    init {
        inflate(context, R.layout.custom_image_button, this)

        // Load the styled attributes and set their properties
        val typedArray = context.obtainStyledAttributes(
            attrs,
            R.styleable.CustomImageButton, defStyleAttr, 0
        )

        val src = typedArray?.getDrawable(R.styleable.CustomImageButton_cib_src)
        val text = typedArray?.getText(R.styleable.CustomImageButton_cib_text)
        val contentDescription = typedArray?.getText(R.styleable.CustomImageButton_cib_contentDescription)

        ivIcon.setImageDrawable(src)
        tvText.text = text
        ivIcon.contentDescription = contentDescription

        typedArray?.recycle()
    }
}

组件XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:toos="http://schemas.android.com/tools"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_width="fill_parent"
        android:layout_height="@dimen/button_height">
    <Button
            android:id="@+id/bClick"
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            android:layout_alignTop="@+id/foreground"
            android:layout_alignBottom="@id/foreground"
            android:layout_alignEnd="@id/foreground"
            android:layout_alignStart="@id/foreground"/>
    <RelativeLayout
            android:id="@id/foreground"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
        <TextView
                android:id="@+id/tvText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:textColor="@color/textWhite"
                toos:text="Some text to test"
                toos:ignore="RelativeOverlap"/>
        <ImageView
                android:id="@+id/ivIcon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_toStartOf="@id/tvText"
                android:paddingTop="1dip"
                android:paddingBottom="1dip"
                android:src="@mipmap/some_image_to_test"
                toos:ignore="ContentDescription"/>
    </RelativeLayout>
</RelativeLayout>

资源属性attrs.xml:

<declare-styleable name="CustomImageButton">
        <attr name="cib_src" format="reference"/>
        <attr name="cib_text" format="string"/>
        <attr name="cib_contentDescription" format="string"/>
    </declare-styleable>

组件使用示例:

<app.package.components.CustomImageButton
            android:id="@+id/cibMyImageButton"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            android:layout_height="wrap_content"
            android:layout_width="match_parent"
            app:cib_src="@mipmap/my_image_to_put_in_the_button"
            app:cib_text="Some text to show in the button"
           app:cib_contentDescription="icon description"/>

答案 10 :(得分:0)

这是一个hack,但是对我来说却是负值:

<Button
    android:id="@+id/some_id"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:drawableStart="@drawable/some_drawable"
    android:drawablePadding="-118dp"
    android:paddingEnd="28dp"
    android:text="@string/some_string" />

更好的方法可能是在自定义视图中执行

答案 11 :(得分:0)

<com.google.android.material.button.MaterialButton
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/your_text"
    app:icon="@drawable/ic_example"
    app:iconGravity="textStart"/>

答案 12 :(得分:-5)

android:layout_gravity="center_vertical|center_horizontal|center" >