Android中如何让Checkbox内的图标居中显示
解决Checkbox图标居中问题
问题描述
我需要让宽高为48x48的Checkbox内的24x24图标居中显示,目前图标位于Checkbox左侧。已经尝试过相关解决方案但无效,现寻求可行方案。相关XML布局代码如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:id="@+id/tags_dialog_tag_item" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?attr/selectableItemBackground" android:clickable="true" android:focusable="true" android:gravity="center_vertical" android:minHeight="?android:attr/listPreferredItemHeight" android:orientation="horizontal" android:paddingBottom="5dp" android:paddingStart="8dp" android:paddingEnd="8dp"> <ImageButton android:id="@+id/id_expand_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/ic_chevron_right_black" android:clickable="false" /> <TextView android:id="@+id/tags_dialog_tag_item_text" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:paddingStart="6dp" android:textSize="16sp" tools:text="Items Text" /> <com.myapp.ui.CheckBoxStates android:id="@+id/tags_dialog_tag_item_checkbox" android:layout_width="48dp" android:layout_height="48dp" android:clickable="false" app:cycle_checked_to_indeterminate="false" app:cycle_indeterminate_to_checked="false"/> </LinearLayout>
可行解决方案
方案1:使用InsetDrawable包裹图标
给Checkbox的选中/未选中状态图标套一层inset drawable,通过设置内边距让图标居中:
- 在
drawable目录下创建checkbox_checked_inset.xml:
<inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="12dp" android:insetRight="12dp" android:insetTop="12dp" android:insetBottom="12dp"> <bitmap android:src="@drawable/你的选中状态图标" /> </inset>
- 同理创建
checkbox_unchecked_inset.xml,替换为未选中状态图标。 - 创建状态选择器
checkbox_state.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/checkbox_checked_inset" android:state_checked="true" /> <item android:drawable="@drawable/checkbox_unchecked_inset" /> </selector>
- 给Checkbox设置该选择器:
<com.myapp.ui.CheckBoxStates android:id="@+id/tags_dialog_tag_item_checkbox" android:layout_width="48dp" android:layout_height="48dp" android:clickable="false" android:button="@drawable/checkbox_state" app:cycle_checked_to_indeterminate="false" app:cycle_indeterminate_to_checked="false"/>
方案2:直接调整Checkbox的padding
通过设置内外边距强制图标居中:
<com.myapp.ui.CheckBoxStates android:id="@+id/tags_dialog_tag_item_checkbox" android:layout_width="48dp" android:layout_height="48dp" android:clickable="false" android:paddingLeft="12dp" android:paddingRight="12dp" android:paddingTop="12dp" android:paddingBottom="12dp" app:cycle_checked_to_indeterminate="false" app:cycle_indeterminate_to_checked="false"/>
注:若自定义Checkbox重写了padding逻辑,此方法可能失效,优先尝试方案1。
方案3:自定义Checkbox的onDraw方法
在CheckBoxStates类中重绘图标位置:
public class CheckBoxStates extends AppCompatCheckBox { // 省略构造方法 @Override protected void onDraw(Canvas canvas) { Drawable buttonDrawable = getButtonDrawable(); if (buttonDrawable != null) { // 计算居中坐标 int centerX = getWidth() / 2; int centerY = getHeight() / 2; int drawableWidth = buttonDrawable.getIntrinsicWidth(); int drawableHeight = buttonDrawable.getIntrinsicHeight(); int left = centerX - drawableWidth / 2; int top = centerY - drawableHeight / 2; int right = left + drawableWidth; int bottom = top + drawableHeight; buttonDrawable.setBounds(left, top, right, bottom); buttonDrawable.draw(canvas); } else { super.onDraw(canvas); } } }
方案4:用布局包裹Checkbox
借助FrameLayout让Checkbox本身居中:
<FrameLayout android:layout_width="48dp" android:layout_height="48dp" android:gravity="center"> <com.myapp.ui.CheckBoxStates android:id="@+id/tags_dialog_tag_item_checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" app:cycle_checked_to_indeterminate="false" app:cycle_indeterminate_to_checked="false"/> </FrameLayout>
内容的提问来源于stack exchange,提问作者oyeraghib
相关产品推荐
相关产品推荐

