笔记119--摘自爱哥06
转自爱哥,快去膜拜:http://blog.csdn.net/aigestudio/article/details/42989325
如果非要对自定义控件的流程进行一个简单的划分,我会尝试将其分为三大部分:控件的绘制、控件的测量和控件的交互行为。
前面用六节篇幅和一个翻页的例子对控件的绘制有了一个全新的认识,下面来看看控件的测量。
1、顶端布局和根布局
setContentView中传入的布局叫顶端布局而不能称为根布局,因为其还有父布局,可通过getParent()验证。其关系如下:
PhoneWindow.DecorView(是FrameLayout的子类)->LinearLayout->FrameLayout->我们的顶端布局。
2、说下View测量逻辑:
View对控件的测量是在onMeasure()中进行的。
View的最终测量尺寸是由view本身和其父容器共同决定的。
MeasureSpec类中的三个Mode常量值的意义,其中UNSPECIFIED表示未指定,爹不会对儿子做任何的束缚,儿子想多大都可以;EXACTLY表示完全的,意为儿子多大爹心里有数,爹早已算好了;AT_MOST表示至多,爹已经为儿子设置好了一个最大限制,儿子你不能比这个值大,不能再多了。父容器所谓的“意图”其实就由上述三个常量值表现,既然如此我们就该对这三个常量做一个判断才行,不然怎么知道爹的意图呢:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // 声明一个临时变量来存储计算出的测量值 int resultWidth = 0; // 获取宽度测量规格中的mode int modeWidth = MeasureSpec.getMode(widthMeasureSpec); // 获取宽度测量规格中的size int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); /* * 如果爹心里有数 */ if (modeWidth == MeasureSpec.EXACTLY) { // 那么儿子也不要让爹难做就取爹给的大小吧 resultWidth = sizeWidth; } /* * 如果爹心里没数 */ else { // 那么儿子可要自己看看自己需要多大了 resultWidth = mBitmap.getWidth(); /* * 如果爹给儿子的是一个限制值 */ if (modeWidth == MeasureSpec.AT_MOST) { // 那么儿子自己的需求就要跟爹的限制比比看谁小要谁 resultWidth = Math.min(resultWidth, sizeWidth); } } int resultHeight = 0; int modeHeight = MeasureSpec.getMode(heightMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); if (modeHeight == MeasureSpec.EXACTLY) { resultHeight = sizeHeight; } else { resultHeight = mBitmap.getHeight(); if (modeHeight == MeasureSpec.AT_MOST) { resultHeight = Math.min(resultHeight, sizeHeight); } } // 设置测量尺寸 setMeasuredDimension(resultWidth, resultHeight);
}
当然上面代码没有考虑到padding,如果有内边距我们需在计算控件尺寸时考虑内边距的大小:
resultWidth = mBitmap.getWidth() + getPaddingLeft() + getPaddingRight();
resultHeight = mBitmap.getHeight() + getPaddingTop() + getPaddingBottom();
看上图,上边距和左边距为什么没有?原因很简单,因为我们在绘制时并没有考虑到Padding的影响,下面更改下绘制逻辑:
@Override
protected void onDraw(Canvas canvas) { // 绘制位图 canvas.drawBitmap(mBitmap, getPaddingLeft(), getPaddingTop(), null);
}
关于margin外边距呢?外边距轮不到view来算,Android将其封装在LayoutParams内交由父容器统一处理。
笔记119--摘自爱哥06相关推荐
- MongoDB笔记记录(雷哥课堂)–基本命令
MongoDB笔记记录(雷哥课堂)–基本命令 3 常用命令 3.1 数据库操作 3.1.1 选择和创建数据库 use 数据库名称 如果数据库不存在就自动创建,如果存在则选择该数据库 以下数据库名是保留 ...
- 【Effection C++】读书笔记 条款05~条款06
[Effection C++]读书笔记 Part2 构造/析构/赋值运算 条款05:了解C++默认编写并调用哪些函数 编译器可以暗自为class创建default构造函数,copy构造函数,copy ...
- 前端学习笔记(HTMLCSS)(06)CSS盒子模型练习
前端学习笔记(HTML&CSS)(06) 练习一:图片列表 <!DOCTYPE html> <html lang="en"> <head> ...
- 马哥 mysql教学笔记_【马哥linux学员学习笔记】MySQL多实例详解
本文作者系马哥linux学员云中鹤. 学习联系QQ:1660809109.1661815153.2813150558 马哥Linux运维 更多资讯:www.magedu.com 目录 一.基本概念 1 ...
- Linux学习笔记1(鸟哥的私房菜)
计算机概述(一) *题外话:本人也是刚学linux,想着看书做一下笔记来提高自己,写的不好勿喷,只为自己,谢谢!* 计算机的组成 我们可以想象一下我们的台式电脑,有鼠标.键盘,然后就是显示屏或者打印机 ...
- 支持向量机SVM--sklearn.svm.SVC【机器学习笔记简摘】
SVM 是一个非常优雅的算法,具有完善的数学理论,常用于数据分类,也可以用于数据的回归预测中,由于其优美的理论保证和利用核函数对于线性不可分问题的处理技巧, 在上世纪90年代左右,SVM 曾红极一时. ...
- 基类成员的public访问权限在派生类中变为_C++ 派生类的构造函数(学习笔记:第7章 06)...
派生类的构造函数[1] 默认情况 基类的构造函数不被继承; 派生类需要定义自己的构造函数. C++11规定 可用using语句继承基类构造函数. 但是只能初始化从基类继承的成员. 派生类新增成员可以通 ...
- 【LeetCode笔记】剑指 Offer 06. 从尾到头打印链表(Java、翻转链表)
文章目录 题目描述 思路 & 代码 二刷 题目描述 思路 & 代码 一次遍历:翻转链表 + 记录长度 二次遍历:遍历翻转后的链表,更新数组 O(n) & O(1) /*** D ...
- AndroidStudio安卓原生开发_SwipeRefreshLayout_下拉刷新控件---Android原生开发工作笔记119
然后我们再来看一个SwipeRefreshLayout,这个是用来实现下拉刷新的一个UI控件. 注意这个SwipeRefreshLayout里面只能放一个子view,一般都是放一个listview.来 ...
最新文章
- arcgis栅格计算器python教程_ArcGIS栅格计算器
- 图解HTTP学习记录(一)
- UIImage与Iplimage相互转换
- linux配置文件、日志文件全备份
- 二维码扫描开源库ZXing定制化【转】
- Jmeter测试计划无法保存或者另存为
- 传统密码学(三)——转轮密码机
- 生活杂谈-简单电器维修知识-2
- dhcp设置(Padavan dhcp设置)
- 清除计算机策略,利用组策略清除历史记录
- IOS版Telegram启用中文界面的方法
- GNU通用公共许可协议--GPLV3中文翻译
- ss3ex集成Beet记录日志
- vivo怎么切换为Android,vivox60怎么切换系统
- 去哪儿网2015年春季校园招聘技术笔试题
- 人性的弱点摘录和感悟
- 计算机考研面试题复习
- 沈阳大学生招聘2020计算机,2020—毕业生必备的各大就业信息网站汇总
- 关于jquery定时器设置问题 ios定时器无法响应问题 ios 时间显示为NaN问题 优惠时间倒计时
- 【FT2000/4+X100】调试记录2--如何让生成X100固件