我想在按钮上显示TEXT
和Icon
。
+----------------------------+
| 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" />
但Text
和Icon
不在中心位置
根据文字大小Text
,我的Icon
尺寸会有所不同,而Text
应调整到中心位置。
我该怎么办?
答案 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" >