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

4.1 初识 ViewRoot 和 DecorView

  1. ViewRoot 对应于 ViewRootImpl 类,连接 WindowManager 和 DecorView 的纽带
  2. View 的三大流程均通过 ViewRoot 完成
ViewRoot#performTraversals
ViewGroup                             View 
performMeasure   measure  onMeasure   measure
performLayout    layout   onLayout    layout
performDraw      draw     onDraw        draw

  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带有滑动嵌套情形时,需要处理滑动冲突
发布了40 篇原创文章 · 获赞 15 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_44947117/article/details/104136751
今日推荐