View的工作原理与自定义View

1.ViewRoot & DecorView

  • ViewRoot (ViewRootImpl) : 连接WindowManager 和 DecorView的纽带
     root = new ViewRootImpl(view.getContext() , display);
     root.setView(view , wparams , panelParentView);

View的绘制流程是从ViewRoot的performTraversals方法开始。
这里写图片描述
measure过程决定View的宽高( getMeasuredWidth() & getMeasuredHeight() ),几乎所有的情况下它都等于View最终的宽高

draw过程决定了View的显示

  • DecorView作为顶级View,一般会包含一个竖直方向的LinearLayout(标题栏+内容栏)
    setContentView()所设置的布局文件就是被加到内容栏之中,id为content
    ViewGroup content = findViewById(R.android.id.content) 得到内容栏
    content.getChildAt(0)得到设置的View
    这里写图片描述

2.MeasureSpec

  • 32位的int值,高2位代表SpecMode , 低30位代表SpecSize
  • SpecMode : UNSPECIFIED (不做限制,用于系统内部), EXACTLY(具体的数值和match_parent) , AT_MOST(wrap_content)

注意: 对于DecorView(顶级View),其MeasureSpec由窗口的尺寸和自身的LayoutParams决定

对于普通的View,其MeasureSpec由父容器的MeasureSpec和自身的LayoutParams决定

UNSPECIFIED : getSuggestedMinimumWidth() getSuggestedMinimumHeight()的返回值就是在此模式下测量的宽高

3.View的工作流程

  • measure -> onMeasure()
  • layout -> ViewGroup用来确定子元素的位置 ; layout() 确定View本身的位置 , onLayout()确定所有子元素的位置
  • draw() 遵循以下几步: 绘制背景,绘制自己,绘制children , 绘制装饰

4.自定义View

自定义View需要主要的地方:

  • 让View支持wrap_content(onMeasure中处理AT_MOST)
  • 支持padding(如果有必要的话)
    对于View: 若不在draw中处理padding,那么padding属性不起作用
    对于ViewGroup: 需要在onMeasure , onLayout中考虑padding和子元素的margin对其造成的影响
  • 尽量不要在View中使用Handler,没必要
  • View中若有线程或动画,需要及时停止(不可见和在onDetachedFromWindow()),避免造成内存泄漏
  • 若有滑动嵌套需处理好滑动冲突
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值