自定义View触摸反馈:基本原理

View.dispatchTouchEvent()只能消费事件
ViewGroup.dispatchTouchEvent()才能分发事件


总结:事件都是从ACTION_DOWN开始的,Activity的dispatchTouchEvent()首先接收到ACTION_DOWN,执行super.dispatchTouchEvent(ev),事件向下分发。相当于ACTION_DOWN导致了决定了分发谁来处理这个事件;之后ACTION_MOVE也从Activity开始,一步一步往下走到ACTION_DOWN决定的事件,开始处理事件冲突;在这个过程中上层随时可以拦截下层的行动
https://blog.csdn.net/xyz_lmn/article/details/12517911

1.⾃定义单 View 的触摸反馈

做法:重写 onTouchEvent(),在⽅法内部定制触摸反馈算法

  • 1.是否消费事件取决于 ACTION_DOWN 事件是否返回 true
    若最顶部的View已被消费,则它底层的View无论是否被消费都没有作用了
  • 2.多点触控应选择getActionMasked() 而不是 getAction()
  • 3.POINTER_DOWN / POINTER_UP:多点触控时的事件。表示非第一根手指按下/抬起

2.View.onTouchEvent() 的源码逻辑(主要处理了点击、长按、右键点击)

1.当⽤户按下(ACTION_DOWN):

  • 1.1如果不在滑动控件中,切换⾄按下状态,并注册⻓按计时器


  • 1.2如果在滑动控件中,切换⾄预按下状态,并注册按下计时器


    • 1.3在非滑动的自定义Layout中应重写,来防止点击延迟


2.当进⼊按下状态并移动(ACTION_MOVE):

  • 2.1重绘 Ripple Effect
  • 2.2如果移动出⾃⼰的范围,⾃我标记本次事件失效,忽略后续事件

3.当⽤户抬起切换⾄抬起状态(ACTION_UP),并清除⼀切状态:

  • 3.1如果是按下状态并且未触发⻓按,切换⾄抬起状态并触发点击事件,并清除
    ⼀切状态
  • 3.2如果已经触发⻓按,切换⾄抬起状态并清除⼀切状态

4.当事件意外结束(ACTION_CANCEL):

切换⾄抬起状态(ACTION_MOVE),并清除⼀切状态

3.⾃定义 ViewGroup 的触摸反馈


所以当父ViewGroup需要消费事件的时候需要重写以下两个方法


  • Activity.dispatchTouchEvent()
    • 递归: ViewGroup(View).dispatchTouchEvent()
      ViewGroup.onInterceptTouchEvent()
      child.dispatchTouchEvent()
      super.dispatchTouchEvent()
      - View.onTouchEvent()
    • Activity.onTouchEvent()

disPatchTouchEvent()基本原理

你可能感兴趣的:(自定义View触摸反馈:基本原理)