View 自定义 - 概览

一、体系

详见:Activity、Window、DecorView、ViewRoot 之间的关系

二、绘制前的准备 DecorView

详见:DecorView

顶部图中可以看出 ViewRoot 最后一步是绘制,在绘制之前系统会有一些准备,即前面几个步骤:创建PhoneWindow、DecorView、ViewRootmpl。

三、View类中的方法

详见:View类中的方法

构造

View(context)

单参构造:代码中 new 创建实例的时候调用。

View(context, attrs)

双参构造:xml中使用时调用(xml转java代码的时候反射),attrs是xml中的属性。

View(context, attrs, defStyleAttr)

三参构造:使用主题Style的时候调用。
绘制过程

onFinishInflate()

当View和他的所有子控件被XML布局文件填充完成时被调用。

onMeasure()

当测量View和它的子View的尺寸需求时被调用。

onLayout()

当View给他的子View分配大小和位置的时候调用。

onSizeChanged()

当view尺寸发生变化时调用。
事件处理

onKeyDown()

按下按键时调用。

onKeyUp()

抬起按键时调用。

onTouchEvent()

触摸屏幕时调用。
焦点

onFocusChanged()

获取到或者失去焦点时调用。

onWindowFocusChanged()

窗口获取或者失去焦点时调用。
attach

onAttachedToWindow()

当View被连接到一个窗口时调用。

onDetachedFromWindow()

当View从窗口分离时调用。

onWindowVisibilityChanged()

当View的窗口的可见性发生改变时调用。

四、自定义控件的不同方式

详见:不同实现方式

复用已有控件复用布局文件
组合现有的控件
扩展已有的控件继承特定的View(如TextView)
继承特定的ViewGroup(如LinearLayout)
完全自定义直接继承 View主要是实现 onMeasure() + onDraw(),因为没有子元素需要布局。
需要自己实现 wrap_content、padding,不需要自己实现 margin 该属性是由父容器决定的。
直接继承 ViewGroup主要是实现 onMeasure() + onLayout(),因为子元素都绘制好了父容器不需要额外绘制。
需要自己实现 wrap_content、padding、margin。

五、绘制流程

从 DecorView 中可以看出 View 的绘制流程开始于ViewRootImpl 对象的 performTraversals(),从视图树根节点(即 DecorView 它是个 ViewGroup)开始由上向下遍历测绘(DecorView→中间层ViewGroup→最底层View)。 

七、自定义流程

构造函数只执行一次,而 onMeasure()、onLayout()、onDraw() 随着控件的刷新可能会执行很多次,因此用到的对象(如 Paint)需要定义成全局变量(避免频繁创建销毁造成内存抖动),在生命周期方法中使用前需要重置(避免每次执行都拿到用过的数据)。

7.1 重写构造自定义属性

详见:属性 Attribute

在 xml 中为控件设置的属性。

  • 自定义属性名称如果使用系统已定义的,例如 textSize 会在编译时报错。

7.2 重写测量、布局、绘制

自定义 View 主要是实现 onMeasure() + onDraw(),因为没有子元素需要布局。自定义 ViewGroup 主要是实现 onMeasure() + onLayout(),因为子元素都绘制好了父容器不需要额外绘制。 

Measure 过程测量控件的宽高performMeasure() → measure() → onMeasure() → 子控件的 Measure 过程。
Layout 过程

确定控件最终宽高在父容器中的位置

(即四个顶点位置)

performLayout() → layout() → onLayout() → 子控件的 Layout 过程。
Draw 过程将控件绘制在屏幕上performDraw() → draw() → onDraw() → 子控件的 Draw 过程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值