CheckBox实现原理分析

news2024/9/8 23:49:41

CheckBox 是 Android 中的一个常用控件,用于实现复选框的功能。它继承自 CompoundButton,后者又继承自 ButtonCheckBox 可以用来表示一个布尔值的选择状态,通常用于收集用户的选择,例如在表单中选择多个选项。

接下来,我们将结合源码来分析 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,它继承自 ButtonCheckBox 主要通过设置按钮图标和监听选中状态的变化来实现其功能。它还支持通过自定义属性来自定义样式,并且可以通过事件监听器来响应状态的变化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1957942.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pip install albumentations安装下载遇19kB/s超级慢细水管解决办法

albumentations 是一个用于图像增强的 Python 库&#xff0c;它提供了丰富的图像变换功能&#xff0c;可以用于数据增强&#xff0c;从而提高深度学习模型的泛化能力。 直接安装命令&#xff1a; pip install albumentations但是如果半夜遇到这种19kB/s的下载速度 为头发着想&…

【通信模块】LoRa与LoRaWAN简介

LoRaWAN网络 技象科技相关文章总结&#xff0c;学习笔记&#xff0c;原文链接如下&#xff0c;转载请标明该出处&#xff1a; LORA&#xff1a; https://www.techphant.cn/tag/l-2 LORAWAN&#xff1a;https://www.techphant.cn/tag/l-3 其他&#xff1a;如LAN https://www…

网络通信---TCP协议1

今日内容 三次握手: 指建立tcp连接时&#xff0c;需要客户端和服务端总共发送三次报文确认连接。 四次挥手&#xff1a; 断开一个tcp连接&#xff0c;需要客户端和服务端发送四个报文以确认断开。 编程模型 TCP报文 客户端 服务端

第6篇文献研读生态廊道相关综述

该文发在生态与农村环境学报。该文章写了生态廊道概念的发展历程、生态廊道类型及功能、生态廊道划定的理论和方法、生态廊道的时间和国内大型生态廊道建设实践。 这篇文章可以让大家了解生态廊道的知识。

Rocketmq-5.3.0和对应dashboard的最新版本Docker镜像,本人亲自制作,部署十分方便,奉献给大家

一、Rocketmq 最新版本5.3.0&#xff0c;采用docker镜像安装方式 二、官方rocketmq镜像对内存等参数配置非常不灵活便利 为了快速、灵活部署rocketmq&#xff0c;以及能方便对其内存等参数进行设置&#xff0c;特意制作了关于它的docker镜像。 三、镜像获取 最新rocketmq-5.…

使用二进制来理解数据和二进制的计算

1 使用二进制来理解数据 和人类的思维习惯不同的是&#xff0c;计算机将把所有的东西数字化之后才会进行处理。那么计算机能理解的数字是什么样的呢&#xff1f;其实&#xff0c;在计算机内部&#xff0c;不管是什么信息都使用二进制来保存和处理的。 计算机为什么要用二进制…

芋道微服务全栈开发日记(商品sku数据归类为规格属性)

商品的每一条规格和属性在数据库里都是单一的一条数据&#xff0c;从数据库里查出来后&#xff0c;该怎么归类为对应的规格和属性值&#xff1f;如下图&#xff1a; 在商城模块&#xff0c;商品的单规格、多规格、单属性、多属性功能可以说是非常完整&#xff0c;如下图&#x…

搭建规范化的vue2项目

项目包含的库 Vue2VuexRouterEslintPrettier 环境 vue&#xff1a;2.6.14 eslint&#xff1a;7.32.0 prettier&#xff1a;2.4.1 eslint-plugin-prettier&#xff1a;4.0.0 eslint-plugin-vue&#xff1a;8.0.3 vue/cli&#xff1a;5.0.8 步骤 全局安装cli工具 npm in…

Vue3----扩展 element Plug card

扩展 element Plug card 增加全屏&#xff0c;折叠操作项 核心代码 <template><div class"cc-card-component"><el-card v-if"state.isShow" :class"state.class" :bodyStyle"bodyStyle" :shadow"props.shadow…

ic进阶|性能篇02:一文带你了解一种特殊的并行技术-展开!

本期文章让我们聊聊一种数字ic设计技术——展开&#xff0c;展开用于产生一个一次迭代就相当于原有结构的多次迭代的新电路结构。其相当于之前聊过的折叠技术的反向操作&#xff0c;折叠使用一个功能单元通过多次迭代来完成原有电路结构一次迭代的操作&#xff0c;相对于通过时…

访问控制列表(ACL)

文章目录 ACL原理与基本配置ACL分类ACL组成ACL规则的匹配与应用 ACL原理与基本配置 ACL(Access Control List&#xff0c;访问控制列表) 读取二层、三层、四层报文信息根据预先定义好的规则对报文进行过滤和分类实现网络访问控制、防止网络攻击和提高网络带宽利用率等目的提高…

USB3.0的等长要求到底是多少?

USB2.0与USB3.0接口的PCB布局布线要求PCB资源PCB联盟网 - Powered by Discuz! (pcbbar.com) 90欧姆阻抗&#xff0c;走差分线&#xff1a; 重点来了&#xff1a;

cf场+线性dp

Problem - B - Codeforces 思路&#xff1a; 这其实是一道数学题&#xff08;最开始一直在枚举&#xff0c;服啦&#xff09; 我们的目的是求最大利润 当a>b是时直接令k0,利润n*a即可 当a<b时存在两种情况&#xff1a; 1.b-a>n即所有b-i1的情况都>a&#xff0…

【数据结构】哈希表二叉搜索树详解

&#x1f48e; 欢迎大家互三&#xff1a;2的n次方_ &#x1f48e;所属专栏&#xff1a;数据结构与算法学习 &#x1f341;1. 二叉搜索树 二叉搜索树也称为二叉查找树或二叉排序树&#xff0c;是一种特殊的二叉树结构&#xff0c;它的特点是&#xff1a; 1. 若左树不为空&am…

SCI算法!发文首选!参数优化下的BiLSTM-KAN模型回归预测,Python代码

声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类算法的家人&#xff0c;可关注我的VX公众号&#xff1a;python算法小当家&#xff0c;不定期会有很多免费代码分享~ KAN是2024年最新的算法&#xff0c;是近期非常热门的一…

leetcode112. 路径总和 leetcode113. 路径总和II,图文并茂,教你完全弄懂DFS,附详细代码

leetcode112. 路径总和 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 …

实验2-3-8 计算火车运行时间

//实验2-3-8 计算火车运行时间 /* 输入格式&#xff1a;输入在一行中给出2个4位正整数&#xff0c;其间以空格分隔&#xff0c;分别表示火车的出发时间和到达时间。 每个时间的格式为2位小时数&#xff08;00-23&#xff09;和2位分钟数&#xff08;00-59&#xff09;&#xff…

从0到1,AI我来了- (4)AI图片识别的理论知识-II

上篇文章&#xff0c;我们理解了我们程序的神经网络设计&#xff0c;这篇我们继续&#xff0c;把训练迭代过程分析一下&#xff0c;完成这两篇文章&#xff0c;下面问题&#xff0c;应该能回答了。 一张图片&#xff0c;如何被计算机读懂&#xff1f;pytorch 封装的网络&#…

C语言实现K均值聚类

K均值聚类(K_means)基础理论 K_means聚类是一种简单且广泛使用的聚类算法&#xff0c;它旨在将数据集中的样本划分为k个不同的聚类&#xff0c;其中k是事先指定的聚类数量&#xff0c;该算法的核心思想是迭代地优化聚类中心&#xff0c;以最小化每个样本与其所属聚类中心之间的…

数据仓库中的DIM层-定义、设计与最佳实践

在当今数据驱动的商业环境中,构建高效的数据仓库架构至关重要。本文将深入探讨数据仓库中的维度层(DIM层),帮助您了解其定义、重要性以及设计最佳实践。 目录 什么是DIM层?DIM层的重要性DIM层设计最佳实践1. 选择适当的粒度2. 实施慢速变化维度(SCD)3. 使用代理键4. 规范化v…