-
ViewRoot对应ViewRootImpl类,它是连接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot来完成的。
-
DecorView作为顶级View,一般情况下它内部会包含一个竖直方向的LinearLayout,在这个LinearLayout里面有上下两个部分,上面是标题栏,下面是内容栏。在Activity中我们通过setContentView所设置的布局文件其实就是被加到内容栏之中的。DecorView其实是一个FrameLayout,View层的事件都先经过DecorView,然后才传递给我们的View。
-
MeasureSpec代表一个32位的int值,高2位代表SpecMode,低30位代表SpecSize,SpecMode是指测量模式,而SpecSize是指在某种测量模式下的规格大小。这样可以避免过多的内存分配。
SpecMode有三类:- UNSPECIFIED
父容器不对View有任何限制。 - EXACTLY
父容器已经检测出View所需要的精确大小,这个时候View的最终大小就是SpecSize所指定的值,它对应于LayoutParams中的match_parent和具体的数值两种模式。 - AT_MOST
父容器指定了一个大小即SpecSize,View的大小不能大于这个值,它对应于LayoutParams中的wrap_content。
- UNSPECIFIED
-
LayoutParams需要和父容器一起才能决定View的MeasureSpec,从而进一步决定View的宽高。
-
获取View的宽高
- view.post(runnable)
- ViewTreeObserver
-
自定义View尽量不要在View中使用Handler,没必要。
-
View中如果有线程或者动画,需要及时停止,参考View#onDetachedFromWindow。
post的原理
View.post() 时,其实内部它自己分了两种情况处理,当 View 还没有 attachedToWindow 时,通过 View.post(Runnable) 传进来的 Runnable 操作都先被缓存在 HandlerActionQueue,然后等 View 的 dispatchAttachedToWindow() 被调用时,就通过 mAttachInfo.mHandler 来执行这些被缓存起来的 Runnable 操作。从这以后到 View 被 detachedFromWindow 这段期间,如果再次调用 View.post(Runnable) 的话,那么这些 Runnable 不用再缓存了,而是直接交给 mAttachInfo.mHanlder 来执行。
网友评论