读书笔记|《Android开发艺术探索》读书笔记--第4章 View的工作原理


文章目录

    • 4.1 初识 ViewRoot 和 DecorView
    • 4.2 理解 MeasureSpec
    • 4.3 View 的工作流程
    • 4.4 自定义 View
      • 4.4.1 自定义View分类
【读书笔记|《Android开发艺术探索》读书笔记--第4章 View的工作原理】
4.1 初识 ViewRoot 和 DecorView
  1. ViewRoot 对应于 ViewRootImpl 类,连接 WindowManager 和 DecorView 的纽带
  2. View 的三大流程均通过 ViewRoot 完成
ViewRoot#performTraversals ViewGroupView performMeasuremeasureonMeasuremeasure performLayoutlayoutonLayoutlayout performDrawdrawonDrawdraw

  1. DecorView 其实是一个 FrameLayout
4.2 理解 MeasureSpec
  1. MeasureSpec:一个32位int值,高2位代表SpecMode(测量模式),低30位代表SpecSize(规格大小)
模式 简介
UNSPECIFIED 要多大就多大
EXACTLY 精确模式,match_parent、具体数值
AT_MOST 最大模式, wrap_content
  1. 对于 DecorView ,MeasureSpec 由窗口尺寸和自身的 LayoutParams 共同决定
  2. 普通 View,由 父容器的 MeasureSpec 和自身 LayoutParams 决定。
结论(getChildeMeasureSpec)
View采用固定宽/高,不管父容器 MeasureSpec 是什么,View的 MeasureSpec 都是 精确模式
View 为 match_parent,1.父容器是精确模式,View是精确模式,大小是父容器剩余空间;2.父容器是最大模式,View也是最大模式,大小不会超过父容器剩余空间
View的宽/高是wrap_content,不管父容器是精确还是最大化,View模式总是最大化,并且不能超过父容器剩余空间
4.3 View 的工作流程
流程 View ViewGroup
measure(测量) 1.measure就完成测量过程;2.measure是一个final,子类不可重写,看onMeasure ;3.onMeasure中getMeasuredWidth/Height拿到View宽高,可能不准,需要 onLayout 方法中;4.Activity/View#onWindowFocusChanged;5.view.post();6.ViewTreeObserver(getViewTreeObserver().addOnGlobalLayoutListener); 7.view.measure(补充) 1.完成自己测量过程,还要遍历去调用所有子元素measure方法,各个子元素在measure;2.measureChildren;3.onMeasure 需要子类去重写
layout(布局) 1.layout 确定 View 本身位置;2.步骤:setFrame设定View四个顶点位置,接着调用 onLayout 方法,用途是父容器确定子元素位置;3.onLayout 与具体布局有关,View 和 ViewGroup 均没有真正实现 onLayout
draw(绘制) 1.绘制背景backgroud.draw(canvas);2.绘制自己(onDraw);3.绘制children(dispatchDraw);4.绘制装饰;(onDrawScrollBars)。 5.setWillNotDraw,如果一个View不需要绘制任何内容,设置 true,系统优化
view.measure 1.具体的数值 int width = MeasureSpec.makeMeasureSpec(100,MeasureSpec.EXACTLY) int heigth= MeasureSpec.makeMeasureSpec(100,MeasureSpec.EXACTLY) view.measure(width ,heigth)2.wrap_content int width = MeasureSpec.makeMeasureSpec((1<<30)-1,MeasureSpec.AT_MOST) int heigth= MeasureSpec.makeMeasureSpec((1<<30)-1,MeasureSpec.AT_MOST) view.measure(width ,heigth)

  1. getWidth/getMeasureWidth 区别
    在View默认实现中,View测量宽/高和最终宽高相等,只不过测量宽高形成与View的measure,而最终宽高形成View的layout过程。
4.4 自定义 View 4.4.1 自定义View分类
分类
继承View重写OnDraw wrap_content,padding
继承ViewGroup派生特殊Layout 测量、布局
继承特定View(tv)
继承特定ViewGroup(ll)
须知
让View支持wrap_content 在 onMeasure 中对 wrap_content
如果有必要,让Viw支持padding draw 中处理 padding,直接继承 ViewGroup 要在 onMeasure 和 onLayout 汇总 考虑 padding 和 子元素 margin 对其造成的影响,不让导致 padding 和 子元素 margin 失效
尽量不要在view中使用Handler post
如果有线程或动画,要及时停止,参考 View#onDetachedFromWindow
View带有滑动嵌套情形时,需要处理滑动冲突

    推荐阅读