Android-View的工作原理(1)

①ViewRoot的performTraversals()开始View的绘制流程,依次调用performMeasure()、performLayout()和performDraw()

②performMeasure()最终执行父容器的measure()方法,并依此执行所有子View的measure方法。

③performLayout()和performDraw()同理

3、View三大流程的作用

①measure决定了View的宽/高,测量后可以通过getMeasuredWidth/Height来获得View测量后的宽/高,除特殊情况外该值等于View最终的宽/高

②layout决定了View的顶点坐标以及实际View的宽/高:完成后可以通过getTop/Bottom/Left/Right获取顶点坐标,并通过getWidth/Height()获得View的最终宽/高

③draw决定了View的显示,最终将View显示出来
MeasuredWidth/height != getWidth/Height()的场景:更改View的布局参数并进行重新布局后,就会导致测量 != 实际值

4、DecorView的作用

①DecorView是顶级View,本质就是一个FrameLayout

②包含了两个部分,标题栏和内容栏

③内容栏id是content,也就是activity中setContentView所设置的部分,最终将布局添加到id为content的FrameLayout中

④获取content:ViewGroup content = findViewById(R.android.id.content)

⑤获取设置的View:content.getChidlAt(0)

5、ViewRootIml如何和DecorView建立联系

①Activity对象在ActivityThread中创建完毕后,会将DecorView添加到Window中

②同时会创建ViewRootImpl,调用ViewRoot的setView方法将ViewRootImpl和DevorView建立关联

6、ViewRoot为什么要和DecorView建立关联

DecorView等View的三大流程需要通过ViewRoot完成

MeasureSpec

1、MeasureSpec是什么?
①MeasureSpec是一种“测量规则”或者“测量说明书”,决定了View的测量过程

②View的MeasureSpec会根据自身的LayoutParamse和父容器的MeasureSpec生成。

③最终根据View的MeasureSpec测量出View的宽/高(测量时数据并非最终宽高)
2、MeasureSpec要点解析
①MeasureSpec代表一个32位int值,高2位是SpecMode,低30位是SpecSize

②SpecMode是指测量模式

③SpecSize是指在某种测量模式下的大小

④类MesaureSpec提供了用于SpecMode和SpecSize打包和解包的方法
3、测量模式SpecMode的类型
①UNSPECIFIED:父容器不对View有任何限制,一般用于系统内部

②EXACTLY:精准模式,View的最终大小就是SpecSize指定的值(对应于LayoutParams的match_parent和具体的数值)

③AT_MOST:最大值模式,大小不能大于父容器指定的值SpecSize(对应于wrap_content)
4、MeasureSpec和LayoutParams的对应关系
①View的MeasureSpec是需要通过自身的LayoutParams和父容器的MeasureSpec一起才能决定

②DecorView(顶级View)是例外,其本身MeasureSpec由窗口尺寸和自身LayoutParams共同决定

③MeasureSpec一旦确定,onMeasure中就可以确定View的测量宽/高
5、普通View的Measure的创建规则
①View本身布局参数为具体dp/px数值,模式:EXACTLY,尺寸:自身尺寸(不管父容器的MeasureSpec)

②View为match_parent, 模式:EXACTLY/AT_MOST由父容器MeasureSpec决定,尺寸:父容器目前可用大小

③View为wrap_content,模式:AT_MOST,尺寸:父容器可用尺寸(不能超过该尺寸)

④当父容器为UNSPECIFIED时,View为具体数值时规则不变;其余match_parent/wrap_content,模式均为:UNSPECIFIED,尺寸:0

⑤UNSPECIFIED一般用于系统内部多次measure的情况,不需要关注该模式
555.png
WechatIMG126.jpeg

View的工作流程

①measure:测量——确定View的测量宽/高

②layout:布局——确定View的最终宽/高和四个顶点的位置

③draw:绘制——将View绘制到屏幕上
1、Measure 过程
1、View的measure过程及要点
①View的measure方法是final类型方法——表明该方法无法被重载

②View的measure方法会调用onMeasure方法,onMeasure会调用setMeasuredDimension方法设置View宽/高的测量值
2、View的onMeasure源码要点

//1. setMeasuredDimension方法设置View宽/高的测量值
setMeasuredDimension(
//2. 第一个参数是获得的测量宽/高(通过getDefaultSize获取)
getDefaultSize(getSuggestedMinimumWidth(), //3. 获取的建议最小的宽/高
widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(),
heightMeasureSpec));
}

1.setMeasuredDimension方法设置View宽/高的测量值(测量值通过getDefaultSize获取)

2.getDefaultSize用于获取View的测量宽/高

3、View的getDefaultSize源码要点(决定了View宽高的测量值)

public static int getDefaultSize(int size, int measureSpec) {
int result = size;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);

switch (specMode) {
//2. UNSPECIFIED模式时,宽/高为第一个参数也就是getSuggestedMinimumWidth()获取的建议最小值
case MeasureSpec.UNSPECIFIED:
result = size;
break;
//3. AT_MOST(wrap_content)和EXACTLY(match_parent/具体值dp等)这两个模式下,View宽高的测量值为当前View的MeasureSpec(测量规格)中指定的尺寸specsize
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result;
}

4、View的getSuggestedMinimumWidth/Height()源码要点

protected int getSuggestedMinimumWidth() {
return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
}

1.如果View没有背景,View的最小宽度就为android:minWidth这个参数指定的值(mMinWidth),没有指定则默认为0

2.如果View有背景,会从mMinWidth和背景的最小宽度中取最大值。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

结尾

最后小编想说:不论以后选择什么方向发展,目前重要的是把Android方面的技术学好,毕竟其实对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!

当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

想要拿高薪实现技术提升薪水得到质的飞跃。最快捷的方式,就是有人可以带着你一起分析,这样学习起来最为高效,所以为了大家能够顺利进阶中高级、架构师,我特地为大家准备了一套高手学习的源码和框架视频等精品Android架构师教程,保证你学了以后保证薪资上升一个台阶。

当你有了学习线路,学习哪些内容,也知道以后的路怎么走了,理论看多了总要实践的。

高级UI,自定义View

UI这块知识是现今使用者最多的。当年火爆一时的Android入门培训,学会这小块知识就能随便找到不错的工作了。

不过很显然现在远远不够了,拒绝无休止的CV,亲自去项目实战,读源码,研究原理吧!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

吧!

[外链图片转存中…(img-S8l0H1tn-1713776729094)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值