ANDROID自定义视图——onMeasure,MeasureSpec源码 流程 思路详解

本文详述Android自定义View中onMeasure的流程和MeasureSpec的机制,包括MeasureSpec的size和mode,以及如何在子类中重写onMeasure进行精确测量。通过实例分析了measureChildren、measureChild和getChildMeasureSpec的方法应用,帮助理解不同约束条件下子View的测量规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介:

在自定义view的时候,其实很简单,只需要知道3步骤:

1.测量——onMeasure():决定View的大小

2.布局——onLayout():决定View在ViewGroup中的位置

3.绘制——onDraw():如何绘制这个View。

而第3步的onDraw系统已经封装的很好了,基本不用我们来操心,只需要专注到1,2两个步骤就中好了。

而这篇文章就来谈谈第一步,也是十分关键得一步:“测量(Measure)


Measure():

Measure的中文意思就是测量。所以它的作用就是测量View的大小。

而决定View的大小只需要两个值:宽详细测量值(widthMeasureSpec)和高详细测量值(heightMeasureSpec)。也可以把详细测量值理解为视图View想要的大小说明(想要的未必就是最终大小)。

对于详细测量值(measureSpec)需要两样东西来确定它,那就是大小(size)和模式(mode)。measureSpec,size,mode他们三个的关系,都封装在View类中的一个内部类里,名叫MeasureSpec


MeasureSpec:

因为MeasureSpec类很小,而且设计的很巧妙,所以我贴出了全部的源码并进行了详细的标注。(掌握MeasureSpec的机制后会对整个Measure方法有更深刻的理解。)

/**
 * MeasureSpec封装了父布局传递给子布局的布局要求,每个MeasureSpec代表了一组宽度和高度的要求
 * MeasureSpec由size和mode组成。
 * 三种Mode:
 * 1.UNSPECIFIED
 * 父不没有对子施加任何约束,子可以是任意大小(也就是未指定)
 * (UNSPECIFIED在源码中的处理和EXACTLY一样。当View的宽高值设置为0的时候或者没有设置宽高时,模式为UNSPECIFIED
 * 2.EXACTLY
 * 父决定子的确切大小,子被限定在给定的边界里,忽略本身想要的大小。
 * (当设置width或height为match_parent时,模式为EXACTLY,因为子view会占据剩余容器的空间,所以它大小是确定的)
 * 3.AT_MOST
 * 子最大可以达到的指定大小
 * (当设置为wrap_content时,模式为AT_MOST, 表示子view的大小最多是多少,这样子view会根据这个上限来设置自己的尺寸)
 * 
 * MeasureSpecs使用了二进制去减少对象的分配。
 */
public class MeasureSpec {
		// 进位大小为2的30次方(int的大小为32位,所以进位30位就是要使用int的最高位和倒数第二位也就是32和31位做标志位)
        private static final int MODE_SHIFT = 30;
        
        // 运算遮罩,0x3为16进制,10进制为3,二进制为11。3向左进位30,就是11 00000000000(11后跟30个0)
        // (遮罩的作用是用1标注需要的值,0标注不要的值。因为1与任何数做与运算都得任何数,0与任何数做与运算都得0)
        private static final int MODE_MASK  = 0x3 << MODE_SHIFT;

        // 0向左进位30,就是00 00000000000(00后跟30个0)
        public static final int UNSPECIFIED = 0 << MODE_SHIFT;
        // 1向左进位30,就是01 00000000000(01后跟30个0)
        public static final int EXACTLY     = 1 << MODE_SHIFT;
        // 2向左进位30,就是10 00000000000(10后跟30个0)
        public static final int AT_MOST     = 2 << MODE_SHIFT;

        /**
         * 根据提供的size和mode得到一个详细的测
<think>好的,我现在要解决用户在Python中遇到的ModuleNotFoundError: No module named 'matplotlib'的问题。首先,我需要了解这个错误的原因。根据引用中的信息,这个错误通常是因为Python环境中没有安装matplotlib库,或者安装的路径与当前使用的解释器不匹配。 首先,用户可能已经通过pip安装了matplotlib,但在PyCharm中运行时仍然报错。这可能是因为PyCharm使用的是不同的Python解释器,而用户安装的库在另一个环境中。例如,用户可能在全局环境中安装了matplotlib,但PyCharm项目使用的是虚拟环境,这时候需要确保虚拟环境中也安装了该库。 接下来,我需要逐步检查可能的解决方案。第一步是确认matplotlib是否已正确安装。用户可以在终端运行pip list查看已安装的包,检查是否有matplotlib及其版本。如果没有,需要重新安装,可能加上清华镜像源加快下载速度,如引用4提到的命令:pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple。 如果已经安装但问题依旧,可能是PyCharm的解释器设置问题。用户需要检查PyCharm中的项目解释器是否指向正确的Python环境。可以在PyCharm的设置中,找到项目解释器选项,添加或选择已安装matplotlib的环境路径。如果项目使用的是虚拟环境,需要在该环境中重新安装matplotlib。 另外,可能存在多个Python版本导致的问题。比如系统同时安装了Python2和Python3,用户可能误将库安装在Python2下,而PyCharm使用的是Python3。这时候需要确认pip命令对应的Python版本,可以使用pip3 install matplotlib来指定Python3的安装。 还有权限问题,特别是在Linux或macOS系统中,如果用户没有使用sudo权限安装,可能导致库安装在用户目录而非系统目录,而PyCharm可能没有权限访问。这时可以尝试使用pip install --user matplotlib,或者在虚拟环境中安装。 最后,如果所有方法都无效,可能需要重新安装PyCharm或检查系统环境变量是否正确配置,确保PATH中包含正确的Python路径。 总结起来,解决步骤大致如下:检查安装情况→确认PyCharm解释器路径→处理多版本问题→检查权限和环境变量。需要根据具体情况逐一排查,确保每个环节都正确无误。</think>### 逐步解决方案:如何解决Python中ModuleNotFoundError: No module named 'matplotlib'错误? #### 1. **确认模块是否已安装** - 在终端输入以下命令,检查是否已安装`matplotlib`: ```bash pip list | grep matplotlib ``` - 若未找到,需重新安装: ```bash pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple # 使用清华镜像加速[^4] ``` #### 2. **检查PyCharm的解释器设置** - 打开PyCharm → 进入项目 → 点击顶部菜单栏 **File → Settings → Project: [项目名] → Python Interpreter**。 - 确认当前选择的解释器路径是否与终端安装`matplotlib`的Python环境一致。例如: - 系统全局环境路径:`/usr/bin/python3` - 虚拟环境路径:`项目目录/venv/bin/python` - 若不一致,需切换解释器或在该环境下重新安装`matplotlib`[^1][^3]。 #### 3. **处理多版本Python冲突** - 如果系统存在多个Python版本(如Python2和Python3),需明确安装目标: - 使用`pip3`安装(针对Python3): ```bash pip3 install matplotlib ``` - 检查PyCharm是否指向正确的Python3解释器。 #### 4. **在PyCharm中手动安装模块** - 在PyCharm的Python Interpreter界面,点击`+`按钮,搜索`matplotlib`并安装(适用于虚拟环境)。 #### 5. **检查权限问题(Linux/macOS)** - 若安装时提示权限不足,尝试: ```bash sudo pip install matplotlib # 系统级安装(需谨慎) 或 pip install --user matplotlib # 用户目录安装 ``` #### 6. **验证安装结果** - 在PyCharm中新建Python文件,输入以下代码运行: ```python import matplotlib.pyplot as plt print(plt.__version__) ``` - 若输出版本号(如`3.5.2`),则安装成功。 --- ### 相关问题 1. **如何为PyCharm项目配置独立的虚拟环境?** *(涉及`venv`模块或`conda`环境管理)* 2. **Python中如何管理不同版本的依赖库?** *(使用`requirements.txt`或`pipenv`工具)* 3. **为什么在终端能导入的模块在PyCharm中报错?** *(解释器路径不一致导致,参考步骤2)[^1]*
评论 40
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值