Android视图绘制流程和原理分析

本文详细介绍了Android视图的绘制流程,包括Activity如何加载ViewRootImpl,View的measure()测量、layout()布局和draw()绘制三个阶段。重点解析了MeasureSpec的生成规则、测量模式以及ViewGroup和View的测量与布局区别,还探讨了自定义视图的常见问题。
摘要由CSDN通过智能技术生成

作为一个Android开发人员,我们每天开发工作都会与View打交道,Android提供的任何布局,控件都是直接或者间接的继承View的,如LinearLayout,RelativeLayout,TextView,Button,ImageView,RecyclerView,ListView等;这些都是Android系统本身就提供好的,我们只需要拿过来使用就可以了,有时候我们需要自定义一些布局,那我们就需要知道View如何绘制到屏幕上?,以便我们能更好完成开发工作;

Activity启动以后如何完成View的绘制工作呢?首页我们就需要了解Activity启动以后的绘制View执行流程;

1.View绘制流程源码路径

1.1Activity加载ViewRootImpl

ActivityThread.handleResumeActivity() 
--> WindowManagerImpl.addView(decorView, layoutParams) 
--> WindowManagerGlobal.addView()
WindowManagerGlobal.addView()负责创建ViewRootImpl,同时执行root.setView(view, wparams, panelParentView);

1.2ViewRootImpl启动View树的遍历

ViewRootImpl.setView(decorView, layoutParams, parentView)
-->ViewRootImpl.requestLayout()
-->scheduleTraversals()
-->TraversalRunnable.run()
-->doTraversal()
-->performTraversals()(performMeasure、performLayout、performDraw)

以上是Activity启动以后View绘制的关键流程,任何一个视图都不是凭空突然出现在屏幕上,它们都是要经过非常科学的绘制流程才能显示出来,通过以上关键流程发现真正绘制是视图主要包含三个阶段performMeasure(测量),performMeasure(布局),performDraw(绘制),下面我们逐个对这三个阶段展开讨论;

2.View绘制流程

2.1measure()测量

measure是测量的意思,那么onMeasure()方法顾名思义就是用于测量视图的大小的。View系统的绘制流程会从ViewRoot的performTraversals()方法中开始,在其内部调用View的measure()方法。measure()方法接收两个参数,widthMeasureSpec和heightMeasureSpec,这两个值分别用于确定视图的宽度和高度的测量模式和大小。

首先要了解视图的宽度和高度的测量模式和大小是使用MeasureSpec表示;

(1).MeasureSpec怎么表示视图的测量模式和大小

重写过onMeasure()方法都知道,测量需要用到MeasureSpec类获取View的测量模式和大小,那么这个类是怎样存储这两个信息呢?

留心观察的话会发现,onMeasure方法的两个参数实际是32位int类型数据,即:

00 000000 00000000 00000000 00000000

而其结构为 mode + size ,前2位为mode,而后30位为size;

如何生成MeasureSpec数据?

makeMeasureSpec()方法(mode + size --> measureSpec)

MeasureSpec
public static int makeMeasureSpec(@IntRange(from = 0, to = (1 << MeasureSpec.MODE_SHIFT) - 1) int size,
                                          @MeasureSpecMode int mode) {
            if (sUseBrokenMakeMeasureSpec) {
                return size + mode;
            } else {
                return (size & ~MODE_MASK) | (mode & MODE_MASK);
            }
        }

这里解释一下,按位或左侧为size的高2位清零后的结果,右侧为mode的低30位清零后的结果,两者按位或运算的结果正好为高2位mode、低30位size,例:

01000000 00000

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值