Xamarin.Forms:能否创建同时包含文本与字体图标的Button?
嘿,这个问题我之前也碰到过!确实IconizeButton默认只会把文本替换成图标,没法同时显示两者,但其实有几种简单的办法能实现你要的「图标+文本」按钮效果,我给你分享几个常用方案:
方法1:利用TextView的CompoundDrawable特性(最快捷)
因为Button本质是继承自TextView的,而TextView有setCompoundDrawables系列方法,可以在文本的上下左右添加Drawable。我们只需要把FontAwesome的图标转换成IconDrawable,然后设置成Button的CompoundDrawable即可:
// 初始化FontAwesome图标,这里以心形图标为例 IconDrawable heartIcon = new IconDrawable(this, FontAwesomeIcons.fa_heart) .colorRes(R.color.white) // 设置图标颜色 .sizeDp(24); // 设置图标大小(dp单位) // 获取你的Button实例 Button likeButton = findViewById(R.id.btn_like); // 将图标设置在文本左侧,其他方向传null即可 likeButton.setCompoundDrawablesWithIntrinsicBounds(heartIcon, null, null, null); // 设置图标和文本之间的间距(可选) likeButton.setCompoundDrawablePadding(getResources().getDimensionPixelSize(R.dimen.icon_text_gap)); // 设置按钮文本 likeButton.setText("点赞");
这种方法不需要自定义控件,几行代码就能搞定,适合快速实现单个按钮的需求。
方法2:自定义可复用的IconTextButton控件
如果你的项目里很多按钮都需要这种效果,自定义一个封装好的控件会更方便维护。
第一步:定义自定义属性
在res/values/attrs.xml中添加以下属性:
<declare-styleable name="IconTextButton"> <attr name="icon" format="string" /> <!-- FontAwesome图标名称,比如fa_star --> <attr name="iconSize" format="dimension" /> <!-- 图标大小 --> <attr name="iconColor" format="color" /> <!-- 图标颜色 --> <attr name="iconPosition" format="enum"> <enum name="left" value="0" /> <enum name="right" value="1" /> <enum name="top" value="2" /> <enum name="bottom" value="3" /> </attr> <!-- 图标相对于文本的位置 --> </declare-styleable>
第二步:实现自定义Button类
public class IconTextButton extends Button { private String iconName; private int iconSize; private int iconColor; private int iconPosition; public IconTextButton(Context context) { super(context); init(null); } public IconTextButton(Context context, AttributeSet attrs) { super(context, attrs); init(attrs); } public IconTextButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(attrs); } private void init(AttributeSet attrs) { if (attrs != null) { TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.IconTextButton); // 读取自定义属性值,设置默认值 iconName = ta.getString(R.styleable.IconTextButton_icon); iconSize = ta.getDimensionPixelSize(R.styleable.IconTextButton_iconSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24, getResources().getDisplayMetrics())); iconColor = ta.getColor(R.styleable.IconTextButton_iconColor, getCurrentTextColor()); iconPosition = ta.getInt(R.styleable.IconTextButton_iconPosition, 0); ta.recycle(); } // 加载并设置图标 if (!TextUtils.isEmpty(iconName)) { Icon targetIcon = Iconize.findIconForKey(iconName); if (targetIcon != null) { IconDrawable iconDrawable = new IconDrawable(getContext(), targetIcon) .color(iconColor) .size(iconSize); // 根据设置的位置添加图标 switch (iconPosition) { case 0: setCompoundDrawablesWithIntrinsicBounds(iconDrawable, null, null, null); break; case 1: setCompoundDrawablesWithIntrinsicBounds(null, null, iconDrawable, null); break; case 2: setCompoundDrawablesWithIntrinsicBounds(null, iconDrawable, null, null); break; case 3: setCompoundDrawablesWithIntrinsicBounds(null, null, null, iconDrawable); break; } // 设置图标与文本的间距 setCompoundDrawablePadding(getResources().getDimensionPixelSize(R.dimen.icon_text_gap)); } } } // 提供动态修改图标的方法 public void setButtonIcon(String iconName) { this.iconName = iconName; init(null); } }
第三步:在布局中使用
<com.yourpackage.IconTextButton android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="收藏" android:textColor="@color/black" app:icon="fa_star" app:iconColor="@color/yellow" app:iconSize="24dp" app:iconPosition="left" />
方法3:结合MaterialButton(如果用Material Design)
如果你项目用了Material Components库,MaterialButton本身就支持设置图标,直接把FontAwesome的IconDrawable赋值给它的icon属性就行:
MaterialButton cartButton = findViewById(R.id.btn_cart); IconDrawable cartIcon = new IconDrawable(this, FontAwesomeIcons.fa_shopping_cart) .colorRes(R.color.black) .sizeDp(24); cartButton.setIcon(cartIcon); cartButton.setText("购物车"); // 设置图标相对于文本的位置 cartButton.setIconGravity(MaterialButton.ICON_GRAVITY_TEXT_START); // 设置图标和文本的间距 cartButton.setIconPadding(8);
这几种方案都能完美实现「图标+文本」的按钮效果,你可以根据自己的项目需求选择最合适的一种~
内容的提问来源于stack exchange,提问作者Gold.strike
相关产品推荐
相关产品推荐

