CheckBox
是 Android 中的一个常用控件,用于实现复选框的功能。它继承自 CompoundButton
,后者又继承自 Button
。CheckBox
可以用来表示一个布尔值的选择状态,通常用于收集用户的选择,例如在表单中选择多个选项。
接下来,我们将结合源码来分析 CheckBox
的实现原理。
1. CheckBox 类定义
CheckBox
类定义如下:
1public class CheckBox extends CompoundButton {
2 // ...
3}
CheckBox
继承自 CompoundButton
,因此它具备 CompoundButton
的所有功能,并且可以显示文本和图标。
2. 构造函数
CheckBox
的构造函数如下:
1public CheckBox(Context context) {
2 this(context, null);
3}
4
5public CheckBox(Context context, AttributeSet attrs) {
6 this(context, attrs, android.R.attr.checkboxStyle);
7}
8
9public CheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
10 super(context, attrs, defStyleAttr);
11 init(context, attrs, defStyleAttr, 0);
12}
构造函数中调用了 init
方法来初始化 CheckBox
的属性。
3. 初始化
初始化方法会设置默认属性,并读取自定义属性。
1private void init(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
2 // ...
3 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CheckBox, defStyleAttr, defStyleRes);
4 // ...
5 // 读取样式属性
6 mButtonDrawable = a.getDrawable(R.styleable.CheckBox_button);
7 // ...
8 a.recycle();
9 // 初始化文本和图标
10 initCompoundButton();
11}
4. 设置按钮图标
CheckBox
通常会显示一个图标来表示选中状态。
1@Override
2public void setButtonDrawable(Drawable buttonDrawable) {
3 super.setButtonDrawable(buttonDrawable);
4 // ...
5}
5. 状态变化
CheckBox
可以通过 setChecked
方法来改变选中状态。
1public void setChecked(boolean checked) {
2 if (checked != mChecked) {
3 mChecked = checked;
4 refreshDrawableState();
5 if (!mPressed) {
6 sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
7 }
8 performClick();
9 }
10}
6. 状态集
CheckBox
使用状态集来管理不同的状态下的外观。
1@Override
2protected int[] onCreateDrawableState(int extraSpace) {
3 final int[] drawableState = super.onCreateDrawableState(extraSpace + 2);
4 if (isChecked()) {
5 mergeDrawableStates(drawableState, CHECKED_STATE_SET);
6 }
7 if (isPressed()) {
8 mergeDrawableStates(drawableState, PRESSED_STATE_SET);
9 }
10 return drawableState;
11}
7. 绘制
CheckBox
重写了 onDraw
方法来绘制文本和图标。
1@Override
2protected void onDraw(Canvas canvas) {
3 super.onDraw(canvas);
4 // ...
5 // 绘制文本和图标
6 if (mButtonDrawable != null) {
7 mButtonDrawable.setBounds(mButtonRect);
8 mButtonDrawable.draw(canvas);
9 }
10 // ...
11}
8. 事件处理
CheckBox
通过处理点击事件来改变选中状态。
1@Override
2public boolean performClick() {
3 toggle();
4 playSoundEffect(SoundEffectConstants.CLICK);
5 return super.performClick();
6}
7
8public void toggle() {
9 setChecked(!mChecked);
10}
9. 焦点和触摸事件
CheckBox
通过处理焦点变化和触摸事件来更新其状态。
1@Override
2public boolean onHoverEvent(MotionEvent event) {
3 // ...
4 return super.onHoverEvent(event);
5}
6
7@Override
8public boolean onTouchEvent(MotionEvent event) {
9 // ...
10 return super.onTouchEvent(event);
11}
10. 适配器模式
CheckBox
通过 CompoundButton
实现了适配器模式,允许同时处理文本和图标。
1public abstract class CompoundButton extends Button implements CompoundButton.OnCheckedChangeListener {
2 // ...
3}
11. 事件监听器
CheckBox
支持通过 OnCheckedChangeListener
监听选中状态的变化。
1public static abstract class OnCheckedChangeListener implements BaseAdapter.DataSetObserver {
2 // ...
3}
4
5public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
6 mOnCheckedChangeListener = listener;
7}
8
9@Override
10public void performClick() {
11 // ...
12 if (mOnCheckedChangeListener != null) {
13 mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
14 }
15 // ...
16}
12. 样式和主题
CheckBox
支持通过 XML 属性来自定义样式。
1<CheckBox
2 android:id="@+id/check_box"
3 android:layout_width="wrap_content"
4 android:layout_height="wrap_content"
5 android:text="Option 1"
6 android:checked="false"
7 android:button="@drawable/check_box_selector" />
总结
CheckBox
的实现基于 CompoundButton
,它继承自 Button
。CheckBox
主要通过设置按钮图标和监听选中状态的变化来实现其功能。它还支持通过自定义属性来自定义样式,并且可以通过事件监听器来响应状态的变化。