自定义View 实践

有时候碰到一些比较奇葩的需求,官方提供的空间没有办法解决, 第三方的控件找起来也麻烦,如果是简单的需求 最好自己熟悉自定义简单的需求。方能不慌不乱。

自定义View,需要了解View 的生命周期,触摸事件的传递,Canvas绘图详解。


View生命周期
1981845-93c81744a1449f22.png
View生命周期
触摸事件的传递
1981845-1e1b66f6c3536ce2.png
触摸事件的传递

触摸事件的理解:一件触摸事件是从手指按下屏幕到手指离开屏幕,这其中所有的触摸都称之为一件触摸事件。强调下:一定要将这个过程中的所有触摸当成一件触摸事件看待。当一个事件不往下分发的时候 这个事件的其他任何触摸都不会传递到下一级,其他事件拦截 也如此。

  • 事件分发 判断当前事件 是否往下分发 。
  • 事件拦截 是否拦截当前事件。(ViewGroup)
  • 事件消费 消费事件,做出业务操作。
Canvas绘图详解

onDraw() 具体证据业务 花自己想要的东西。
Canvas绘图详解


我们知道,不管是自定义View还是系统提供的TextView这些,它们都必须放置在LinearLayout等一些ViewGroup中,因此理论上我们可以很好的理解onMeasure(),onLayout(),onDraw()这三个函数:1.View本身大小多少,这由onMeasure()决定;2.View在ViewGroup中的位置如何,这由onLayout()决定;3.绘制View,onDraw()定义了如何绘制这个View。

首先我们要理解的是widthMeasureSpec, heightMeasureSpec这两个参数是从哪里来的?onMeasure()函数由包含这个View的具体的ViewGroup调用,因此值也是从这个ViewGroup中传入的。这里我直接给出答案:子类View的这两个参数,由ViewGroup中的layout_width,layout_height和padding以及View自身的layout_margin共同决定。权值weight也是尤其需要考虑的因素,有它的存在情况可能会稍微复杂点。
了解了这两个参数的来源,还要知道这两个值的作用。我们只取heightMeasureSpec作说明。这个值由高32位和低16位组成,高32位保存的值叫specMode,可以通过如代码中所示的MeasureSpec.getMode()获取;低16位为specSize,同样可以由MeasureSpec.getSize()获取。那么specMode和specSize的作用有是什么呢?要想知道这一点,我们需要知道代码中的最后一行,所有的View的onMeasure()的最后一行都会调用setMeasureDimension()函数的作用——这个函数调用中传进去的值是View最终的视图大小。也就是说onMeasure()中之前所作的所有工作都是为了最后这一句话服务的。
我们知道在ViewGroup中,给View分配的空间大小并不是确定的,有可能随着具体的变化而变化,而这个变化的条件就是传到specMode中决定的,specMode一共有三种可能:

MeasureSpec.EXACTLY:父视图希望子视图的大小应该是specSize中指定的。
MeasureSpec.AT_MOST:子视图的大小最多是specSize中指定的值,也就是说不建议子视图的大小超过specSize中给定的值。
MeasureSpec.UNSPECIFIED:我们可以随意指定视图的大小。
由TextView中源码也可以知道这个值的设计意义是为了根据ViewGroup中具体能够提供的空间大小来指定子View的视图大小。


1981845-bf444a52e7b1ded5.png
不慌不乱
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值