如何创建具有居中文本和图像且大小设置为 match_parent 的按钮

Posted

技术标签:

【中文标题】如何创建具有居中文本和图像且大小设置为 match_parent 的按钮【英文标题】:How to create button with centered text and image and size set to match_parent 【发布时间】:2012-11-23 06:41:51 【问题描述】:

我想要一个这样的按钮:

+-----------------------+
|                       |
|        +-----+        |
|        |Image|        |
|        +-----+        |
|          Text         |
|                       |
|                       |
+-----------------------+

编辑:图片说明:我希望图像和文本的组合居中(文本始终位于图像下方)

我希望 Button 拉伸到父对象(使整个区域成为按钮单击区域),并且仍然在中心对齐图像和文本。

我使用以下代码仅实现了顶部中心对齐,但我没有得到想要的行为...

<Button
    android:id="@+id/btInfo"
    android:paddingTop="20dp"
    android:layout_
    android:layout_
    android:gravity="top|center_horizontal"                   
    android:layout_weight="1"
    android:background="@drawable/border_button_main_menu"
    android:drawableTop="@drawable/bt_info"
    android:onClick="onClick"
    android:text="@string/info"
    android:textColor="@drawable/bt_white_red_text"
    android:textSize="15dp" />

android:gravity="top|center_horizontal" 更改为android:gravity="center_vertical|center_horizontal" 只会导致图像居中在顶部,文本居中在底部...


---- EDIT2 -----

想要的行为:

1) 看起来像描述的那样(图像和文本是一个光学组,该组位于按钮的中心)

2) 文本应该是按钮的一部分(我希望 onclick 行为与选择器一起使用)


---- EDIT3 -----

添加了我自己的解决方案...但感谢所有尝试提供帮助的人

【问题讨论】:

你为什么要设置 android:drawableTop ?它会将可绘制对象设置在顶部 正如我所说,设置 center_vertical|center_horizo​​ntal 会导致顶部居中的图像和底部居中的文本......离开它也不会导致我想要的行为...... Direct xml thrue 不能做。使用自定义按钮。 我贴了xml代码,请只替换背景图片使用。 我是这么想的,那个直接的xml不能做我想做的所有事情……最后还是得使用自定义按钮…… 【参考方案1】:

使用以下代码,您的问题将得到解决。

<Button
    android:layout_
    android:layout_
    android:layout_alignBottom="@+id/foreground"
    android:layout_alignLeft="@+id/foreground"
    android:layout_alignRight="@+id/foreground"
    android:layout_alignTop="@+id/foreground"
    android:background="@android:drawable/dialog_frame"
    android:onClick="clickedMe" />

   <RelativeLayout
       android:id="@+id/foreground"
       android:layout_
       android:layout_
       android:layout_alignParentBottom="true"
       android:layout_alignParentTop="true" >

       <TextView
           android:id="@+id/button_text"
           android:layout_
           android:layout_
           android:layout_alignParentBottom="true"
           android:layout_centerHorizontal="true"
           android:layout_marginBottom="112dp"
           android:text="@string/hello_world" />

       <ImageView
           android:id="@+id/imageView1"
           android:layout_
           android:layout_
           android:layout_above="@+id/button_text"
           android:layout_centerHorizontal="true"
           android:paddingBottom="10dip"
           android:paddingTop="10dip"
           android:src="@drawable/ic_launcher" />

   </RelativeLayout>

</RelativeLayout>

------------- 编辑 --------

oNclick 方法:

final TextView text = (TextView) findViewById(R.id.button_text);
    RelativeLayout foreground = (RelativeLayout) findViewById(R.id.foreground);
    foreground.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View v) 
            Log.d(TAG, "clicked");
            Toast.makeText(getApplicationContext(), "Clicked...!!!",
                    Toast.LENGTH_LONG).show();
            text.setTextColor(Color.RED);
        
    );

【讨论】:

我在第一篇文章中添加了一些编辑... 是的......这没问题,我知道,但我也希望选择器能够与按钮单击一起工作(在我的情况下,单击按钮时更改文本的颜色......)。 ..无需在代码中手动执行此操作...因为我在很多地方都使用了按钮... 我没有完全理解你的要求。 如果这个答案对你有帮助,那么你应该被检查。 实际上,我想要一个满足我要求的 XML 解决方案(因为我在更多地方使用它)... 第一个要求:单击按钮应该更改文本颜色(因此我会使用选择器) 和第二个要求:以光学为中心的图像组,下方有文字...【参考方案2】:

试试这个:

<LinearLayout
android:gravity="center"
android:layout_
android:layout_>

<Button
android:id="@+id/btInfo"
android:layout_
android:layout_
android:layout_weight="1"
android:background="@drawable/border_button_main_menu"
android:drawableTop="@drawable/bt_info"
android:onClick="onClick"
android:text="@string/info"
android:textColor="@drawable/bt_white_red_text"
android:textSize="15dp" />

</LinearLayout>

【讨论】:

这只能以编程方式工作,因为我事先不知道值... 好的。您还可以做的是代替按钮,您可以使用线性布局并将图像和文本放入其中。然后,您可以在 linearLayout 上实现 onClickListener 并使其像按钮一样执行 谢谢,我知道这行得通...只是想找到一个简单的解决方案...以及开箱即用的点击行为和 android 按钮外观... 感谢您的帮助,但这也不是解决方案......图像和文本的组合应该始终居中......它不能与drawableTop左右一起使用,因为没有中心值...我认为,解决方案是在一个相对布局中设置一个按钮,而不是另一个相对布局(其中包含图像和文本),该布局延伸到完整的相对布局......如链接中所描述的那样。 . 谢谢你的帮助【参考方案3】:

调用setBackgroundDrawable(),然后您将添加到按钮的文本将出现在drawable下方!

【讨论】:

可能图像不够“绘制”清晰,我希望图像和文本的组合“居中”,文本始终位于图像下方...将在上方添加该信息【参考方案4】:

我认为实现这种 UI 的最佳方式是使用 ImageButton 而不是 Button。但是你仍然可以通过一些骇人听闻的方式来实现这一点。其中之一在这里:

How to have Image and Text Center within a Button

您只需在上面链接中给出的解决方案中将内部 RelativeLayout 的方向称为“垂直”。 希望对你有帮助。

也许这对你也有帮助:

How to center icon and text in a android button with width set to "fill parent"

【讨论】:

刚刚又试了一次ImageButton,想知道为什么我没有用它...现在我想起来了,它似乎不支持文字,我不想在图片中添加文字...但链接似乎很好,会研究它...谢谢 对于第一个解决方案,我必须手动编写 ioptical click 更改,因为文本不是按钮的一部分......这实际上是我正在寻找另一个解决方案的原因......如果我不需要,我无论如何都会制作一个线性布局或相对视图并设置 onclick 监听器......无论如何都谢谢【参考方案5】:

您尝试实现的输出无法使用drawableTop 以这种方式完成。

为什么? - 视图可以设置背景或可绘制,而设置可绘制Android 仅提供 4 个选项来设置可绘制的边界,top,left,right or bottom 和 nothing for center

现在在您的 XML 中,您将视图的高度和宽度设置为 MATCH_PARENT,因此每次使用 drawableTOP 或 LEFT 等设置可绘制对象时,它都会到达视图的边缘。这正在发生在你身上。

来自评论:

    Android 操作系统归根结底是一个软件。软件始终是在其范围内开发的。您要问的东西超出了范围,因此使用任何默认表单小部件的 android 直接不支持它..

    我演示了 android 是如何编写 Drawable 类以及如何使用它的,所以请尝试理解答案,而不仅仅是解决您的问题.. 顺便让您点击整个区域可以写点击那个 LinearLayout 而不是按钮。

解决办法是:

<LinearLayout height = MATCH_PARENT and width = 0dp>

    <Button height and width = WRAP_CONTENT with drawableTop=image and gravity = center>

</LinearLayout>

【讨论】:

这只是一种光学解决方案,正如我所提到的,我希望整个区域都是按钮的点击区域... LinearLayout 区域应该与您的情况下的按钮完全重叠 @prom85 我演示了 android 是如何编写 Drawable 类以及如何使用它的,所以请尝试理解答案,而不仅仅是解决您的问题..顺便获得点击整个区域,您可以点击该 LinearLayout 而不是按钮。 我明白你写的东西......而且我知道,它不能那样工作......我只是想知道是否有一个简单的解决方案,而不是使用自定义按钮...... .(刚刚发布了代码以证明我不是在为我的问题寻找解决方案并且还没有尝试过任何东西......)也为我的第一篇文章添加一个大编辑......以显示我想要的内容最终实现 @prom85 Android OS 最终是一个软件......并且已经在它的范围内开发了一个软件。您要问的事情超出了范围,因此使用任何默认表单小部件的 android 直接不支持它。这就是我所说的和再说一遍。仅针对通过搜索来到帖子的其他用户.. 对于他们,我还添加了如何获取行为的解决方案。 我明白你的意思...无论如何,解决方案不是我要找的,它是其他东西的解决方案...虽然,它满足了我的大部分愿望,但不是全部他们……【参考方案6】:

我的解决方案现在来自一个按钮......它满足了我的所有要求......我不知道,如果文本的测量真的如此精确,但它看起来是这样......如果不,每个人都明白背后的想法,并且可以调整它......

谢谢你的帮助

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.widget.Button;

public class CenterImageTextButton extends Button 

    private Paint mPaint = new Paint();
    private String mText = null;
    private float mTextSize = 0;

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

    public CenterImageTextButton(Context context) 
        super(context); 
    

    @Override
    public void onDraw(Canvas canvas) 

        mText = getText().toString();
        mTextSize = getTextSize();

        mPaint.setStyle(Style.FILL); 
        mPaint.setColor(getCurrentTextColor());        

        // get image top
        Drawable drawable = getCompoundDrawables()[1];
        Drawable curDrawable = null;
        if (drawable instanceof StateListDrawable)
            curDrawable = ((StateListDrawable)drawable).getCurrent();
        else
            curDrawable = ((BitmapDrawable)drawable).getCurrent();
        Bitmap image = ((BitmapDrawable)curDrawable).getBitmap();

        // call default drawing method without image/text
        setText("");
        setCompoundDrawables(null, null, null, null);
        super.onDraw(canvas);
        setText(mText);
        setCompoundDrawables(null, drawable, null, null);

        // get measurements of button and Image
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        int imgWidth = image.getWidth();
        int imgHeight = image.getHeight();

        // get measurements of text
        //float densityMultiplier = getContext().getResources().getDisplayMetrics().density;
        //float scaledPx = textSize * densityMultiplier;
        //paint.setTextSize(scaledPx);
        mPaint.setTextSize(mTextSize);
        float textWidth = mPaint.measureText(mText);

        // draw Image and text
        float groupHeight = imgHeight + mTextSize;
        canvas.drawBitmap(image, (width - imgWidth) / 2, (height - groupHeight) / 2, null);
        canvas.drawText(mText, (width - textWidth) / 2, mTextSize + (height - groupHeight) / 2 + imgHeight, mPaint);    
    

【讨论】:

以上是关于如何创建具有居中文本和图像且大小设置为 match_parent 的按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何根据需要调整背景图像的大小

如何保存具有特定文件大小的图像?

具有背景和居中文本的 TextView [关闭]

如何从图像叠加中垂直居中文本

如何在 <li> 网格上调整图像和文本的大小并使其居中?

根据实际可见字母高度在 UILabel 中垂直居中文本