为带图标和文字的IconButton设置Drawable内边距
嘿,我明白你现在的困扰——想用IconButton同时显示图标和文字,还要整体居中,但图标总是贴边,自己写的layer-list又没效果,还不想放弃按钮的涟漪动画对吧?我来给你几个亲测有效的方案:
方案1:给图标本身加内边距(最简单)
你之前尝试的layer-list没生效,是因为把padding加在了selector的item里,这根本不会作用在图标上。正确的做法是直接给你的图标资源btn_ic_done套一个带padding的shape容器,这样图标自身就有内边距了:
<!-- res/drawable/btn_ic_done.xml --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 正常状态 --> <item> <shape> <padding android:left="3dp" android:top="1dp" android:right="3dp" android:bottom="3dp"/> <drawable android:drawable="@drawable/btn_done"/> </shape> </item> <!-- 按压状态(可选,保持和正常状态一致的padding) --> <item android:state_pressed="true"> <shape> <padding android:left="3dp" android:top="1dp" android:right="3dp" android:bottom="3dp"/> <drawable android:drawable="@drawable/btn_done_pressed"/> </shape> </item> </selector>
这样修改后,图标自带内边距,再配合IconButton的android:gravity="center",整体就能完美居中了。
方案2:调整按钮的padding和背景尺寸
你的按钮背景btn_dark.xml里设置了固定的size android:width="110dp" android:height="40dp",但控件用了match_parent,这会导致背景和控件尺寸错位,影响内容的居中效果。试试这两步:
- 删掉背景里的
<size>标签,让背景自适应控件大小; - 给IconButton添加整体padding,让图标和文字不会贴按钮边缘:
<com.phillipcalvin.iconbutton.IconButton android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="16dp" android:background="@drawable/btn_dark" android:drawableLeft="@drawable/btn_ic_done" android:padding="8dp" <!-- 给整个按钮加内边距 --> android:gravity="center" <!-- 让图标+文字整体居中 --> app:iconPadding="10dp" <!-- 图标和文字的间距保持不变 --> android:text="DONE" android:textColor="@color/White"/>
方案3:自定义Drawable(更灵活)
如果上面的方法都满足不了你的需求,比如需要动态调整内边距,那可以写一个自定义Drawable来给图标加padding:
public class PaddingDrawable extends Drawable { private final Drawable mOriginalDrawable; private final int mPaddingLeft; private final int mPaddingTop; private final int mPaddingRight; private final int mPaddingBottom; public PaddingDrawable(Drawable drawable, int left, int top, int right, int bottom) { mOriginalDrawable = drawable; mPaddingLeft = left; mPaddingTop = top; mPaddingRight = right; mPaddingBottom = bottom; // 设置Drawable的边界,预留出padding空间 setBounds(mPaddingLeft, mPaddingTop, mOriginalDrawable.getIntrinsicWidth() + mPaddingLeft + mPaddingRight, mOriginalDrawable.getIntrinsicHeight() + mPaddingTop + mPaddingBottom); } @Override public void draw(@NonNull Canvas canvas) { // 平移画布,留出padding的位置再绘制原图标 canvas.save(); canvas.translate(mPaddingLeft, mPaddingTop); mOriginalDrawable.draw(canvas); canvas.restore(); } @Override public void setAlpha(int alpha) { mOriginalDrawable.setAlpha(alpha); } @Override public void setColorFilter(@Nullable ColorFilter colorFilter) { mOriginalDrawable.setColorFilter(colorFilter); } @Override public int getOpacity() { return mOriginalDrawable.getOpacity(); } }
然后在代码里给按钮设置这个带padding的图标:
IconButton doneBtn = findViewById(R.id.your_button_id); Drawable originalIcon = ContextCompat.getDrawable(this, R.drawable.btn_done); if (originalIcon != null) { Drawable paddedIcon = new PaddingDrawable(originalIcon, 3, 1, 3, 3); doneBtn.setCompoundDrawablesWithIntrinsicBounds(paddedIcon, null, null, null); }
总结
优先试试方案1和方案2,这两个都是纯XML配置,不用写代码,而且能完美保留IconButton的涟漪动画效果。如果需要更灵活的控制,再考虑方案3。
内容的提问来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

