Android开发艺术探索笔记 第四章

Android开发艺术探索笔记 第四章

View的工作原理

基本概念

  • ViewRoot对英语ViewRootImpl类,他是连接WindowManager和DecorView的纽带
  • View的绘制流程是从ViewRoot的performTraversals方法开始的,该方法依次调用performMeasure,performLayout, performDraw。先进行顶级View的measure,layout,draw方法,然后递归遍历view树
  • DecorView其实是一个FrameLayout,一般情况下它内部会包含一个竖直方向的LinearLayout,上面是标题栏,下面是内容栏
  • View层的事件都先传递给DecorView然后在传递给我们的View
  • MesureSpec代表一个32位的int值,高2位代表SpecMode测量模式,低30位代表在该测量模式下的规格大小。设计的目的是避免过多的对象内存分配
  • Exactly,精确大小,Layoutparams指定具体数值和fillparent都属于精确数值
  • *Atmost,父控件指定一个大小view不能超过他,对应于LayoutParams的wrap_content
  • 系统会将LayoutParams在父容器的约束下转换成对应的MeasureSpec,再根据这个MeasureSpec来确定定测量后的宽高,DecorView没有父容器,所以受窗口尺寸约束
  • View采用固定宽高的时候,不管父容器的MeasureSpec是什么,View的MesureSpec都是精确模式
  • View采用match_parent时,父为精确View为精确,父为最大View为最大且不能超过父容器的剩余空间
  • View采用wrap_content时,不管父容器的MesureSpec是什么,View的模式总是最大,且不能超过父容器的剩余空间
  • 以上可以得出结论只要给出父类的MesureSpec和子类的LayoutParams就能推出子类的MesureSpec

View的工作流程

  • View的Mesure方法是final类型的,子类不能重写,但是他会调用onMesure方法
  • View的最终大小是在layout阶段确定的,但是大部分情况下测量大小(MesureSpec)和最终大小是相等的
  • 直接继承View的自定义控件需要重写onMesure方法并设置wrap_content时的大小,否则wrap_content,就相当于使用match_parent
  • ViewGroup是一个抽象类,没有重写View的onMesure方法,需要子类去各自实现,而是有一个ViewGroup方法。思想就是取出子View的lp,算出ms传给子View
  • 一个好的习惯是在onLayout中去获取View的测量宽高或者最终宽高
  • View的Mesure过程和Activity的生命周期方法不是同步执行的,因此无法保证某个Activity的回掉函数时View已经测量完毕了
  • 四个方法解决上面的问题1、回掉函数onWindowFcusChanged;2、View的post一个runnable;3、viewTreeObserver
  • layout方法确定View本身的位置,onLayout方法确定所有子元素的位置

自定义View

  • 直接继承View需要自己支持warp_content(onMeasure中处理),padding(draw中处理),直接继承Viewgroup需要自己处理测量、布局
  • View提供了Post没必要使用Handler
  • onDetachedFromWindow中结束动画是一个很好的时机
  • Margin属性由父控件控制
  • 在构造方法中解析自定义属性,TypedArray试用结束后用recycle方法回收资源
  • 一个典型的schemas声明 xmlns:app=http://schemas.android.com/apk/res-auto

你可能感兴趣的:(Android开发艺术探索笔记 第四章)