如何将宽度设置为“填充父项”的android按钮中的图标和文本居中
Posted
技术标签:
【中文标题】如何将宽度设置为“填充父项”的android按钮中的图标和文本居中【英文标题】:How to center icon and text in a android button with width set to "fill parent" 【发布时间】:2011-04-07 17:53:02 【问题描述】:我想要一个带有图标+文本的 android Button。我正在使用 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:
android:heigh="wrap_content" />
关于如何实现这一目标的任何建议?
【问题讨论】:
这可能没有简单的解决方案吗?我是否必须尝试使用带有图标的 9patch 按钮 img? 这可能是一个解决方案。按钮文本是本地化的还是静态的? 已本地化。没有其他解决方案吗?我设法用一个 9 补丁来做到这一点,但在更改语言环境时遇到了问题。 如何使用带有可绘制 TOP 的 Button 并为其添加一些填充? 糟糕的框架设计 【参考方案1】:android:drawableLeft 始终保持 android:paddingLeft 与左边框的距离。当按钮没有设置为android:时,它会一直挂在左边!
在 Android 4.0(API 级别 14)中,您可以使用 android:drawableStart 属性在文本开头放置一个可绘制对象。我想出的唯一向后兼容的解决方案是使用 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);
在我的情况下,我还需要调整 Button 的 android:gravity 属性以使其看起来居中:
<Button
android:id="@+id/button"
android:layout_
android:layout_
android:minHeight="32dp"
android:minWidth="150dp"
android:gravity="center_horizontal|top" />
【讨论】:
不错。最后一行应该是button.setText(buttonLabel)
Unicode 有大量与 Android 中的字符串兼容的字符图标。如果你能找到一个可以接受的解决方案,这是一个简单的解决方案,而且它还有一个额外的好处,那就是它会随文本大小缩放。例如,它有一个用于电子邮件图标的信封和几个不同的电话作为呼叫按钮。
我很困惑这对任何人来说是如何工作的,对我来说它绘制了 2 个图标......一个向左,一个直接在中心显示在文本顶部。
drawableStart 不起作用。请参阅此线程:***.com/questions/15350990/… 另外,似乎当您使用 spannable 设置文本时,样式会被忽略。
drawableStart 不起作用,在 API 级别 17 中添加以支持 rtl【参考方案2】:
之前所有的答案似乎都已经过时了
您现在可以使用MaterialButton
来设置图标的重力。
<com.google.android.material.button.MaterialButton
android:id="@+id/btnDownloadPdf"
android:layout_
android:layout_
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" />
为了使用材料组件,您显然需要:
添加依赖
implementation 'com.google.android.material:material:1.3.0-alpha01'
(使用最新版本)
让您的主题扩展 Material Components 主题
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
...
</style>
如果您不能这样做,请从 Material Bridge 主题扩展它
<style name="AppTheme" parent="Theme.MaterialComponents.Light.Bridge">
...
</style>
【讨论】:
谢谢!你救了我的一天!工作正常 不必更改整个应用程序主题,您可以通过在 MaterialButton 标签上使用 app:theme 只为按钮本身应用主题【参考方案3】:我知道我回答这个问题迟了,但这对我有帮助:
<FrameLayout
android:layout_
android:layout_
android:layout_marginBottom="5dp"
android:layout_marginTop="10dp"
android:background="@color/fb" >
<Button
android:id="@+id/fbLogin"
android:layout_
android:layout_
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>
我从这里找到了这个解决方案:Android UI struggles: making a button with centered text and icon
【讨论】:
这样的问题是按钮不是框架布局的宽度。【参考方案4】:我使用 LinearLayout 而不是 Button。我需要使用的 OnClickListener 也适用于 LinearLayout。
<LinearLayout
android:id="@+id/my_button"
android:layout_
android:layout_
android:background="@drawable/selector"
android:gravity="center"
android:orientation="horizontal"
android:clickable="true">
<ImageView
android:layout_
android:layout_
android:layout_marginRight="15dp"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/icon" />
<TextView
android:layout_
android:layout_
android:gravity="center"
android:text="Text" />
</LinearLayout>
【讨论】:
【参考方案5】:我通过左右添加padding来调整如下:
<Button
android:layout_
android:layout_
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"
/>
【讨论】:
paddingLeft 和 paddingRight 帮助了我的居中。为简单的解决方案投票。 如何处理宽度是动态的这一事实?如果旋转屏幕,所有图标都不会居中吗?我实际上正面临这个问题 这是最好的答案!【参考方案6】:我最近遇到了同样的问题。试图找到一个更便宜的解决方案,所以想出了这个。
<LinearLayout
android:id="@+id/linearButton"
android:layout_
android:layout_
android:background="@drawable/selector_button_translucent_ab_color"
android:clickable="true"
android:descendantFocusability="blocksDescendants"
android:gravity="center"
android:orientation="horizontal" >
<ImageView
android:layout_
android:layout_
android:contentDescription="@string/app_name"
android:src="@drawable/ic_launcher" />
<TextView
android:layout_
android:layout_
android:text="@string/app_name"
android:textColor="@android:color/white" />
</LinearLayout>
然后只需在LinearLayout
上拨打OnClickListener
。
希望这对某人有所帮助,因为这似乎是一个非常常见的问题。 :)
【讨论】:
这是一个好主意,但却是一个糟糕的解决方案。您可以使用 drawableLeft 属性仅使用一个 TextView 来实现相同的目的。这使您可以查看文本左侧的可绘制对象。 @muetzenflo 是的,没错。但是,当您使 textView 与父宽度匹配时,即使您将文本居中,您的可绘制对象也会移动到最左侧。如果我错了,请告诉我。问题只是关于这个。 啊抱歉..我来这里就是为了这个问题,在尝试了太多东西后失去了注意力:) 猜猜我只见树木不见森林。我的错!【参考方案7】:您可以使用自定义按钮来测量和绘制自身以适应左侧可绘制对象。请查找示例和用法here
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);
用法
<com.mypackage.DrawableAlignedButton
android:layout_
android:layout_
android:layout_weight="1"
android:drawableLeft="@drawable/my_drawable"
android:gravity="center"
android:padding="7dp"
android:text="My Text" />
【讨论】:
您可以在答案中包含代码,这应该是首选方式(如果不是太长的话),因为链接可能会随着时间的推移而失效- 不是很准确,但我接受了 它向右移动文本,但不够(图像与文本重叠)。此外,与其他自定义视图的解决方案一样,它不接受长文本。【参考方案8】:这是我 3 年前写的解决方案。按钮有文本和左图标,并且在框架中,这里是实际的按钮,可以通过 fill_parent 进行拉伸。我无法再次测试它,但它当时正在工作。可能 Button 不必使用,可以用 TextView 代替,但我现在不会测试它,它不会在这里改变太多功能。
<FrameLayout
android:id="@+id/login_button_login"
android:background="@drawable/apptheme_btn_default_holo_dark"
android:layout_
android:layout_gravity="center"
android:layout_>
<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>
【讨论】:
现在我发现我并不孤单:)【参考方案9】:我知道这个问题有点老了,但也许你仍然愿意接受提示或解决方法:
创建一个以按钮图像作为背景或按钮本身作为布局的第一个元素的RelativeLayout“wrap_content”。获取一个 LinearLayout 并将其设置为“layout_centerInParent”和“wrap_content”。然后将您的 Drawable 设置为 Imageview。最后用你的文本(语言环境)设置一个 TextView。
所以基本上你有这个结构:
RelativeLayout
Button
LinearLayout
ImageView
TextView
或者像这样:
RelativeLayout with "android-specific" button image as background
LinearLayout
ImageView
TextView
我知道这个解决方案有很多元素需要处理,但是您可以使用它轻松创建自己的自定义按钮,还可以设置文本和绘图的确切位置:)
【讨论】:
这种方法可以很好地工作。就我而言,我只需要一个包含 TextView 的 RelativeLayout。 RelativeLayout 获得了背景,TextView 获得了 drawableLeft 图标。然后在代码中:如果需要,将 onClickListener 附加到 RelativeLayout 和 findViewById 分别为 TextView 第一个建议结构给出“Button cannot be cast to ViewGroup”异常。【参考方案10】:我解决这个问题的方法是用轻量级的<View ../>
元素包围按钮,这些元素可以动态调整大小。下面是几个例子,说明可以用这个实现什么:
请注意,示例 3 中按钮的可点击区域与示例 2 中的相同(即带有空格),这与示例 4 中的按钮之间没有“不可点击”间隙不同。
代码:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical">
<TextView
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="5dp"
android:layout_
android:layout_
android:textStyle="bold"
android:text="Example 1: Button with a background color:"/>
<LinearLayout
android:layout_
android:layout_>
<View
android:layout_
android:layout_
android:layout_weight="1"/>
<Button
android:layout_
android:layout_
android:text="Button"
android:textColor="@android:color/white"
android:drawableLeft="@android:drawable/ic_secure"
android:drawableStart="@android:drawable/ic_secure"
android:background="@android:color/darker_gray"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:layout_weight="0.3"/>
<!-- Play around with the above 3 values to modify the clickable
area and image alignment with respect to text -->
<View
android:layout_
android:layout_
android:layout_weight="1"/>
</LinearLayout>
<TextView
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="5dp"
android:layout_
android:layout_
android:textStyle="bold"
android:text="Example 2: Button group + transparent layout + spacers:"/>
<LinearLayout
android:layout_
android:layout_>
<View
android:layout_
android:layout_
android:layout_weight="1"/>
<Button
android:layout_
android:layout_
android:text="Button"
android:textColor="@android:color/white"
android:drawableLeft="@android:drawable/ic_secure"
android:drawableStart="@android:drawable/ic_secure"
android:background="@android:color/darker_gray"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_weight="1"/>
<View
android:layout_
android:layout_
android:layout_weight="1"/>
<Button
android:layout_
android:layout_
android:text="Button"
android:textColor="@android:color/white"
android:drawableLeft="@android:drawable/ic_secure"
android:drawableStart="@android:drawable/ic_secure"
android:background="@android:color/darker_gray"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_weight="1"/>
<View
android:layout_
android:layout_
android:layout_weight="1"/>
<Button
android:layout_
android:layout_
android:text="Button"
android:textColor="@android:color/white"
android:drawableLeft="@android:drawable/ic_secure"
android:drawableStart="@android:drawable/ic_secure"
android:background="@android:color/darker_gray"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_weight="1"/>
<View
android:layout_
android:layout_
android:layout_weight="1"/>
</LinearLayout>
<TextView
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="5dp"
android:layout_
android:layout_
android:textStyle="bold"
android:text="Example 3: Button group + colored layout:"/>
<LinearLayout
android:layout_
android:layout_
android:background="@android:color/darker_gray">
<View
android:layout_
android:layout_
android:layout_weight="1"/>
<Button
style="?android:attr/buttonBarButtonStyle"
android:layout_
android:layout_
android:text="Button"
android:textColor="@android:color/white"
android:drawableLeft="@android:drawable/ic_secure"
android:drawableStart="@android:drawable/ic_secure"
android:background="@android:color/darker_gray"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_weight="1"/>
<View
android:layout_
android:layout_
android:layout_weight="1"/>
<Button
style="?android:attr/buttonBarButtonStyle"
android:layout_
android:layout_
android:text="Button"
android:textColor="@android:color/white"
android:drawableLeft="@android:drawable/ic_secure"
android:drawableStart="@android:drawable/ic_secure"
android:background="@android:color/darker_gray"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_weight="1"/>
<View
android:layout_
android:layout_
android:layout_weight="1"/>
<Button
style="?android:attr/buttonBarButtonStyle"
android:layout_
android:layout_
android:text="Button"
android:textColor="@android:color/white"
android:drawableLeft="@android:drawable/ic_secure"
android:drawableStart="@android:drawable/ic_secure"
android:background="@android:color/darker_gray"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_weight="1"/>
<View
android:layout_
android:layout_
android:layout_weight="1"/>
</LinearLayout>
<TextView
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="5dp"
android:layout_
android:layout_
android:textStyle="bold"
android:text="Example 4 (reference): Button group + no spacers:"/>
<LinearLayout
android:layout_
android:layout_
android:background="@android:color/darker_gray">
<Button
style="?android:attr/buttonBarButtonStyle"
android:layout_
android:layout_
android:text="Button"
android:textColor="@android:color/white"
android:drawableLeft="@android:drawable/ic_secure"
android:drawableStart="@android:drawable/ic_secure"
android:background="@android:color/darker_gray"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_weight="1"/>
<Button
style="?android:attr/buttonBarButtonStyle"
android:layout_
android:layout_
android:text="Button"
android:textColor="@android:color/white"
android:drawableLeft="@android:drawable/ic_secure"
android:drawableStart="@android:drawable/ic_secure"
android:background="@android:color/darker_gray"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_weight="1"/>
<Button
style="?android:attr/buttonBarButtonStyle"
android:layout_
android:layout_
android:text="Button"
android:textColor="@android:color/white"
android:drawableLeft="@android:drawable/ic_secure"
android:drawableStart="@android:drawable/ic_secure"
android:background="@android:color/darker_gray"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
【讨论】:
【参考方案11】:尝试使用这个库
OmegaCenterIconButton
【讨论】:
【参考方案12】:您可以创建自定义小部件:
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_
android:layout_
android:clickable="true" >
<ImageView
android:id="@+id/btn_icon"
android:layout_
android:layout_
android:layout_marginRight="2dp"
android:layout_toLeftOf="@+id/btn_text"
android:duplicateParentState="true" />
<TextView
android:id="@+id/btn_text"
android:layout_
android:layout_
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_
android:layout_
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>
为了更好的定位,如果您想避免RelativeLayout定位的潜在问题,请将自定义按钮包装在LinearLayout中。
享受吧!
【讨论】:
【参考方案13】:有类似的问题,但希望有没有文本和没有包装布局的中心可绘制。解决方案是创建自定义按钮并在 LEFT、RIGHT、TOP、BOTTOM 之外再添加一个可绘制按钮。可以轻松地修改可绘制的位置并将其置于相对于文本的所需位置。
CenterDrawableButton.java
public class CenterDrawableButton extends Button
private Drawable mDrawableCenter;
public CenterDrawableButton(Context context)
super(context);
init(context, null);
public CenterDrawableButton(Context context, AttributeSet attrs)
super(context, attrs);
init(context, attrs);
public CenterDrawableButton(Context context, AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
init(context, attrs);
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CenterDrawableButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
super(context, attrs, defStyleAttr, defStyleRes);
init(context, attrs);
private void init(Context context, AttributeSet attrs)
//if (isInEditMode()) return;
if(attrs!=null)
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs, R.styleable.CenterDrawableButton, 0, 0);
try
setCenterDrawable(a.getDrawable(R.styleable.CenterDrawableButton_drawableCenter));
finally
a.recycle();
public void setCenterDrawable(int center)
if(center==0)
setCenterDrawable(null);
else
setCenterDrawable(getContext().getResources().getDrawable(center));
public void setCenterDrawable(@Nullable Drawable center)
int[] state;
state = getDrawableState();
if (center != null)
center.setState(state);
center.setBounds(0, 0, center.getIntrinsicWidth(), center.getIntrinsicHeight());
center.setCallback(this);
mDrawableCenter = center;
invalidate();
requestLayout();
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if(mDrawableCenter!=null)
setMeasuredDimension(Math.max(getMeasuredWidth(), mDrawableCenter.getIntrinsicWidth()),
Math.max(getMeasuredHeight(), mDrawableCenter.getIntrinsicHeight()));
@Override
protected void drawableStateChanged()
super.drawableStateChanged();
if (mDrawableCenter != null)
int[] state = getDrawableState();
mDrawableCenter.setState(state);
mDrawableCenter.setBounds(0, 0, mDrawableCenter.getIntrinsicWidth(),
mDrawableCenter.getIntrinsicHeight());
invalidate();
@Override
protected void onDraw(@NonNull Canvas canvas)
super.onDraw(canvas);
if (mDrawableCenter != null)
Rect rect = mDrawableCenter.getBounds();
canvas.save();
canvas.translate(getWidth() / 2 - rect.right / 2, getHeight() / 2 - rect.bottom / 2);
mDrawableCenter.draw(canvas);
canvas.restore();
attrs.xml
<resources>
<attr name="drawableCenter" format="reference"/>
<declare-styleable name="CenterDrawableButton">
<attr name="drawableCenter"/>
</declare-styleable>
</resources>
用法
<com.virtoos.android.view.custom.CenterDrawableButton
android:id="@id/centerDrawableButton"
android:layout_
android:layout_
app:drawableCenter="@android:drawable/ic_menu_info_details"/>
【讨论】:
谢谢!这就是我一直在寻找的。span> 你能帮我解决这个问题吗,***.com/questions/35912539/…,你的回答我非常接近它,但出现了两个可绘制对象 此解决方案将 drawable 放置在按钮的中心,就在居中的文本上方。【参考方案14】:如果你尝试 android:gravity="center_horizontal" 会发生什么?
【讨论】:
它不起作用。文本有点居中,但 drawableLeft 粘在左侧。 太棒了。谢谢【参考方案15】:<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_
android:layout_ >
<Button
style="@style/captionOnly"
android:layout_
android:layout_
android:layout_gravity="center"
android:drawableLeft="@android:drawable/ic_delete"
android:gravity="center"
android:text="Button Challenge" />
</FrameLayout>
将 FrameLayout 放入 LinearLayout 并将方向设置为水平。
【讨论】:
【参考方案16】:您可以将按钮放在 LinearLayout 上
<RelativeLayout
android:layout_
android:layout_
android:background="@mipmap/bg_btn_fb">
<LinearLayout
android:layout_
android:layout_
android:gravity="center">
<TextView
android:layout_
android:layout_
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_
android:layout_
android:id="@+id/btnLoginFb"
android:background="@color/transparent"
/>
</RelativeLayout>
【讨论】:
【参考方案17】:我认为 android:gravity="center" 应该可以工作
【讨论】:
对我不起作用。它使文本居中,但 drawableLeft 仍位于最左侧。 你必须在同一个父级下声明图标和文本,父级使用android:gravity = "centre"【参考方案18】:正如 Rodja 所建议的,在 4.0 之前,没有直接的方法可以将文本与可绘制对象居中。实际上,设置 padding_left 值确实会将可绘制对象从边框移开。因此我的建议是,在运行时,您可以准确计算出您的可绘制对象需要从左边框有多少像素,然后使用setPadding 传递它 您的计算可能类似于
int paddingLeft = (button.getWidth() - drawableWidth - textWidth) / 2;
你的drawable的宽度是固定的,你可以查看它,你也可以计算或猜测文本的宽度。
最后,您需要将填充值乘以屏幕密度,您可以使用DisplayMetrics 来完成此操作
【讨论】:
【参考方案19】:公共类 DrawableCenterTextView 扩展 TextView
public DrawableCenterTextView(Context context, AttributeSet attrs,
int defStyle)
super(context, attrs, defStyle);
public DrawableCenterTextView(Context context, AttributeSet attrs)
super(context, attrs);
public DrawableCenterTextView(Context context)
super(context);
@Override
protected void onDraw(Canvas canvas)
Drawable[] drawables = getCompoundDrawables();
if (drawables != null)
Drawable drawableLeft = drawables[0];
Drawable drawableRight = drawables[2];
if (drawableLeft != null || drawableRight != null)
float textWidth = getPaint().measureText(getText().toString());
int drawablePadding = getCompoundDrawablePadding();
int drawableWidth = 0;
if (drawableLeft != null)
drawableWidth = drawableLeft.getIntrinsicWidth();
else if (drawableRight != null)
drawableWidth = drawableRight.getIntrinsicWidth();
float bodyWidth = textWidth + drawableWidth + drawablePadding;
canvas.translate((getWidth() - bodyWidth) / 2, 0);
super.onDraw(canvas);
【讨论】:
这对我根本不起作用。你能举个例子吗?也许我没有正确使用它【参考方案20】:脏修复。
android:paddingTop="10dp"
android:drawableTop="@drawable/ic_src"
计算正确的填充解决了目的。但是,对于不同的屏幕,使用不同的填充并将其放在相应值文件夹中的维度资源中。
【讨论】:
【参考方案21】:使用 RelativeLayout(容器)和 android:layout_centerHorizontal="true" ,我的样本:
<RelativeLayout
android:layout_
android:layout_
android:layout_weight="1" >
<CheckBox
android:layout_
android:layout_
android:layout_centerHorizontal="true"
android:layout_gravity="center"
android:layout_marginBottom="5dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:button="@drawable/bg_fav_detail"
android:drawablePadding="5dp"
android:text=" Favorite" />
</RelativeLayout>
【讨论】:
【参考方案22】:保留按钮主题的其他可能性。
<Button
android:id="@+id/pf_bt_edit"
android:layout_
android:layout_
/>
<LinearLayout
android:layout_
android:layout_
android:layout_alignBottom="@id/pf_bt_edit"
android:layout_alignLeft="@id/pf_bt_edit"
android:layout_alignRight="@id/pf_bt_edit"
android:layout_alignTop="@id/pf_bt_edit"
android:layout_margin="@dimen/margin_10"
android:clickable="false"
android:elevation="20dp"
android:gravity="center"
android:orientation="horizontal"
>
<ImageView
android:layout_
android:layout_
android:adjustViewBounds="true"
android:clickable="false"
android:src="@drawable/ic_edit_white_48dp"/>
<TextView
android:id="@+id/pf_tv_edit"
android:layout_
android:layout_
android:layout_marginLeft="@dimen/margin_5"
android:clickable="false"
android:gravity="center"
android:text="@string/pf_bt_edit"/>
</LinearLayout>
如果您添加了这个解决方案 @color/你的颜色 @color/your_highlight_color 在您的活动主题中,您可以在 Lollipop 上使用带有阴影和波纹的 Matherial 主题,而对于以前版本的扁平按钮,您可以在按下它时使用您的颜色和高亮坐标。
此外,使用此解决方案自动调整图片大小
结果: 首先在棒棒糖设备上 第二:在棒棒糖设备上 3th : Pre lollipop device press button
【讨论】:
【参考方案23】:我使用paddingLeft
将textView
与图标居中,并将textView 与left|centerVertical 对齐。对于视图和图标之间的小间隙,我使用了drawablePadding
<Button
android:id="@+id/have_it_main"
android:layout_
android:layout_
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" />
【讨论】:
这不适用于许多屏幕,仅适用于android:paddingLeft
工作的屏幕。【参考方案24】:
这可能是一个旧的/关闭的线程,但我到处搜索都没有找到有用的东西,直到我决定创建自己的解决方案。如果这里有人试图寻找答案,试试这个,可能会节省你一分钟的思考时间
<LinearLayout
android:id="@+id/llContainer"
android:layout_
android:layout_
android:background="@drawable/selector"
android:clickable="true"
android:gravity="center"
android:orientation="vertical"
android:padding="10dp"
android:textStyle="bold">
<TextView
android:layout_
android:layout_
android:gravity="center"
android:text="This is a text" />
<ImageView
android:layout_
android:layout_
android:src="@drawable/icon_image />
</LinearLayout>
因为线性布局充当容器并且拥有选择器,所以当您单击整个线性布局时,它看起来就是它应该的样子。如果您希望它都居中,请使用相对 insteaf。如果您希望它水平居中,请将方向更改为水平。
请注意不要忘记将 android:clickable="true" 添加到您的主容器(相对或线性)以执行操作。
同样,这可能是旧线程,但仍然可以帮助那里的人。
-干杯希望它有所帮助- 快乐编码。
【讨论】:
【参考方案25】:如果您使用自定义视图的解决方案之一,请小心,因为它们经常在长或多行文本上失败。我重写了一些答案,替换了onDraw()
并理解这是错误的方式。
【讨论】:
【参考方案26】:我已经看到了在开始/左侧对齐可绘制对象的解决方案,但对于可绘制对象结束/右侧却没有,所以我想出了这个解决方案。它使用动态计算的填充来对齐左右两侧的可绘制对象和文本。
class IconButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = R.attr.buttonStyle
) : AppCompatButton(context, attrs, defStyle)
init
maxLines = 1
override fun onDraw(canvas: Canvas)
val buttonContentWidth = (width - paddingLeft - paddingRight).toFloat()
val textWidth = paint.measureText(text.toString())
val drawable = compoundDrawables[0] ?: compoundDrawables[2]
val drawableWidth = drawable?.intrinsicWidth ?: 0
val drawablePadding = if (textWidth > 0 && drawable != null) compoundDrawablePadding else 0
val bodyWidth = textWidth + drawableWidth.toFloat() + drawablePadding.toFloat()
canvas.save()
val padding = (buttonContentWidth - bodyWidth).toInt() / 2
val leftOrRight = if (compoundDrawables[0] != null) 1 else -1
setPadding(leftOrRight * padding, 0, -leftOrRight * padding, 0)
super.onDraw(canvas)
canvas.restore()
根据您在哪里设置图标,将布局中的重力设置为“center_vertical|start”或“center_vertical|end”非常重要。例如:
<com.***.util.IconButton
android:id="@+id/cancel_btn"
android:layout_
android:layout_
android:layout_weight="1"
android:drawableStart="@drawable/cancel"
android:drawablePadding="@dimen/padding_small"
android:gravity="center_vertical|start"
android:text="Cancel" />
这个实现的唯一问题是按钮只能有单行文本,否则文本区域会填充按钮并且填充将为0。
【讨论】:
【参考方案27】:试试这个你会找到你要找的,
<Button
android:id="@+id/button_my_profile"
style="@style/whiteTextBlackButtonStyle.size18"
android:layout_
android:layout_weight="1"
android:layout_
android:gravity="center"
android:drawableTop="@drawable/ic_more_profile"
android:drawablePadding="8dp"
android:paddingStart="16dp"
android:text="@string/title_my_profile"
android:textAllCaps="false"
tools:layout_editor_absoluteY="24dp" />
【讨论】:
【参考方案28】:考虑ImageButton
。
android:src
属性可用于设置在 Button 中居中的可绘制对象。
<ImageButton
android:src="@drawable/your_drawable"
...
/>
【讨论】:
【参考方案29】:使用这个
android:background="@drawable/ic_play_arrow_black_24dp"
只需将背景设置为要居中的图标
【讨论】:
以上是关于如何将宽度设置为“填充父项”的android按钮中的图标和文本居中的主要内容,如果未能解决你的问题,请参考以下文章
Android - 获取设置为 wrap_content 的按钮的宽度
Android:如何设置AlertDialog的宽度和高度,以及AlertDialog风格的按钮?