Android_自定义View---三种事件的触发、自定义View属性

View的三种事件触发方式
1、dispatchTouchEvent(MotionEvent ev) 事件分发
2、onInterceptTouchEvent(MotionEvent ev) 事件拦截
3、onTouchEvent(MotionEvent event) 事件响应
其中的事件拦截onInterceptTouchEvent 只有ViewGroup中存在
activity:
这里写图片描述
自定义ViewGroup:
这里写图片描述

自定义View:
这里写图片描述
xml:
这里写图片描述

-分发拦截响应
activity默认(false)默认
ViewGroup默认默认默认
View默认默认默认

这里写图片描述
首先通过activity分发—->ViewGroup分发—->ViewGroup拦截—->View分发
activity响应<—-ViewGroup响应<—-View响应

当都为默认值时的执行顺序

这里写图片描述

ViewGroup与View均不响应事件时,则activity响应,当下次再次有事件activity不会向下分发而是自己响应

-分发拦截响应
activity默认(false)默认
ViewGrouptrue默认默认
View默认默认默认

activity的分发为true时
这里写图片描述
ViewGroup的分发为true
这里写图片描述
View的分发为true时
这里写图片描述
当分发的返回值为true时,代表当前View的分发消耗了事件,则就向下一级发出事件

ViewGroup的拦截为true
这里写图片描述
当ViewGroup的拦截为true时,也不会向下一级(View)发出事件,与分发不同的是,拦截不会消耗时间,转而发给响应事件
当响应事件为true时
activity的响应为true
这里写图片描述

ViewGroup的响应为true

这里写图片描述
View的响应为true

这里写图片描述
当响应时间为true时不会影响事件的向下分发,但是在往回(View–activity)调用响应事件时,当返回值为true则消耗了事件,便不会再往上一级发事件

源码中的逻辑
1.enabled =false之后,我们是不是就接收不到事件了?
能够拿到事件,但是监听没有触发
这里写图片描述
可以看出enabled 的值只是在事件中做一个逻辑判断,并不影响事件的执行

2.enabled =false之后,为什么监听,选择器就失效了?
3.为什么只有clickble=true,选择器才生效

2,3的原因如下:
在onTouchEvent中有一下代码,当enable=false时,直接return,不会往下执行。只有为true时才会执行下列代码
这里写图片描述
4.为什么setOnClickListener之后,我们即使不设置clickble=true,选择器也生效
这里写图片描述
原因在于当调用onClickListener方法时,会将cliclkable设置成true
并将监听赋值给ListenerInfo中

5.为什么dispatchTouchEvent会优先于onTouchEvent和onInterceptTouchEvent执行
原因在于在View源码的dispatchTouchEvent()方法中有以下代码
这里写图片描述
可以看出onTouchEvent方法是在dispatchTouchEvent方法的内部执行的

1、其中的result指的是当前dispatchTouchEvent()的返回值,当dispatchTouchEvent()的返回值为true在最后一个if中的‘半路与’操作中!result = false,就不会调用后面的onTouchEvent(),从以上代码可以看出,当满足了内部的第一个if中的条件result才会变成true从而也不会执行onTouchEvent()

2、当我们的返回值为true时,不调用父类的dispatchTouchEvent()方法(上面展示的View的dispatchTouchEvent()方法),所以不会调用到父类中dispatchTouchEvent()的onTouchEvent()了
所以dispatchTouchEvent为true时onTouchEvent不会执行

这里写图片描述

但是当手动调用父类的dispatchTouchEvent时,无论当前控件的dispatchTouchEvent()的返回值是否为true,均会调用到当前空间的onTouchEvent

6.为什么OnTouchListener会优先于OnClickListener执行,为什么OnTouchListener retrun true,OnClickListener就不执行了
这里写图片描述
这里写图片描述
同5:OnClickListener方法在OnTouchListener中执行,在OnTouchListener中执行onTouch()方法,当onTouch()返回值为true时result为true,由下面的if ’短路与‘操作!result=false,所以不会执行到onTouchEvent()方法。然而在onTouchEvent()方法中有一下代码:
这里写图片描述
performClick():
这里写图片描述
可以看出在onClick()在onTouchEvent()中执行
综上所述 OnTouchListener return true时,dispatchTouchEvent中的result为true,当result为true时,短路与的if不会执行onTouchEvent()方法,所以更不会执行onTouchEvent()中的onClick()方法

7.ListenerInfo(一种思想)
当前控件所有监听的封装,同一管理
作用在于当控件使用到某些监听时,把这些监听全部赋值给ListenerInfo中的监听变量,这样,当我们需要覆写好的监听时,只需要在ListenerInfo中获取就行了
8.performClick….
这里写图片描述

自定义View属性
1、在资源文件中定义属性
这里写图片描述
这里写图片描述
2、在View中调用
这里写图片描述

自定义的属性需要自定义的前缀 “xx:”默认为“app:”,无论什么前缀都需要引入文件
xmlns:xx=”http://schemas.android.com/apk/res-auto” 代表该前缀修饰的属性自动在res文件下寻找。

3、在java中编写属性的逻辑
①、在什么view用,就要继承什么view
这里写图片描述
②、获取该view中所有属性集合
这里写图片描述
在TypedArray后调用recycle主要是为了缓存。当recycle被调用后,这就说明这个对象从现在可以被重用了。TypedArray 内部持有部分数组,它们缓存在Resources类中的静态字段中,这样就不用每次使用前都需要分配内存。

③、编写逻辑
repeatNum(attrs):

这里写图片描述

textOrientation(attrs):

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值