当前位置: 代码迷 >> 综合 >> android 的事件分发(dispatchTouchEvent),拦截(onInterceptTouchEvent)与处理(onTouchEvent)相关
  详细解决方案

android 的事件分发(dispatchTouchEvent),拦截(onInterceptTouchEvent)与处理(onTouchEvent)相关

热度:56   发布时间:2023-10-19 06:14:34.0

看了这个写的触摸事件觉得很容易读懂,所以这里也去实践一下,顿时就昏了,哎先附上这篇文章

Android的事件分发(dispatchTouchEvent),拦截(onInterceptTouchEvent)与处理(onTouchEvent)

我们都是知道两点:

1 view 只有两个相关方法,事件分发(dispatchTouchEvent)和处理事件(onTouchEvent)处理事件是必须有的

2 viewGroup 有三个方法比view多了一个拦截事件(onInterceptTouchEvent)事件分发(dispatchTouchEvent)和处理事件(onTouchEvent)

viewGroup 是继承view的

这里也引用上面文章 的方法,两个viewgroup 和一个view

android 的事件分发(dispatchTouchEvent),拦截(onInterceptTouchEvent)与处理(onTouchEvent)相关

 

其中myviewGroupA 如下:

import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.widget.LinearLayoutclass MyViewGroupA(context: Context?, attrs: AttributeSet?) : LinearLayout(context, attrs) {override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {when (ev?.action) {MotionEvent.ACTION_DOWN -> {Log.e("mlt","---MyViewGroupA---dispatchTouchEvent_ ACTION_DOWN----------------")}MotionEvent.ACTION_MOVE -> {Log.e("mlt","---MyViewGroupA---dispatchTouchEvent_ ACTION_MOVE----------------")}MotionEvent.ACTION_UP-> {Log.e("mlt","---MyViewGroupA---dispatchTouchEvent_ ACTION_UP----------------")}}return super.dispatchTouchEvent(ev)}override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {when (ev?.action) {MotionEvent.ACTION_DOWN -> {Log.e("mlt","---MyViewGroupA---onInterceptTouchEvent ACTION_DOWN----------------")}MotionEvent.ACTION_MOVE -> {Log.e("mlt","---MyViewGroupA---onInterceptTouchEvent ACTION_MOVE----------------")}MotionEvent.ACTION_UP-> {Log.e("mlt","---MyViewGroupA---onInterceptTouchEvent ACTION_UP----------------")}}return super.onInterceptTouchEvent(ev)}@SuppressLint("ClickableViewAccessibility")override fun onTouchEvent(event: MotionEvent?): Boolean {when (event?.action) {MotionEvent.ACTION_DOWN -> {Log.e("mlt","---MyViewGroupA---onTouchEvent ACTION_DOWN----------------")}MotionEvent.ACTION_MOVE -> {Log.e("mlt","---MyViewGroupA---onTouchEvent ACTION_MOVE----------------")}MotionEvent.ACTION_UP-> {Log.e("mlt","---MyViewGroupA---onTouchEvent ACTION_UP----------------")}}return super.onTouchEvent(event)}
}

myviewGroupB

class MyViewGroupB(context: Context?, attrs: AttributeSet?) : LinearLayout(context, attrs) {override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {when (ev?.action) {MotionEvent.ACTION_DOWN -> {Log.e("mlt","---MyViewGroupB---dispatchTouchEvent_ ACTION_DOWN----------------")}MotionEvent.ACTION_MOVE -> {Log.e("mlt","---MyViewGroupB---dispatchTouchEvent_ ACTION_MOVE----------------")}MotionEvent.ACTION_UP-> {Log.e("mlt","---MyViewGroupB---dispatchTouchEvent_ ACTION_UP----------------")}}return super.dispatchTouchEvent(ev)}override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {when (ev?.action) {MotionEvent.ACTION_DOWN -> {Log.e("mlt","---MyViewGroupB---onInterceptTouchEvent ACTION_DOWN----------------")}MotionEvent.ACTION_MOVE -> {Log.e("mlt","---MyViewGroupB---onInterceptTouchEvent ACTION_MOVE----------------")}MotionEvent.ACTION_UP-> {Log.e("mlt","---MyViewGroupB---onInterceptTouchEvent ACTION_UP----------------")}}return super.onInterceptTouchEvent(ev)}@SuppressLint("ClickableViewAccessibility")override fun onTouchEvent(event: MotionEvent?): Boolean {when (event?.action) {MotionEvent.ACTION_DOWN -> {Log.e("mlt","---MyViewGroupB---onTouchEvent ACTION_DOWN----------------")}MotionEvent.ACTION_MOVE -> {Log.e("mlt","---MyViewGroupB---onTouchEvent ACTION_MOVE----------------")}MotionEvent.ACTION_UP-> {Log.e("mlt","---MyViewGroupB---onTouchEvent ACTION_UP----------------")}}return super.onTouchEvent(event)}
}

myview:

class MyView(context: Context?, attrs: AttributeSet?) : View(context, attrs) {override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {when (ev?.action) {MotionEvent.ACTION_DOWN -> {Log.e("mlt","---MyView---dispatchTouchEvent_ ACTION_DOWN----------------")}MotionEvent.ACTION_MOVE -> {Log.e("mlt","---MyView---dispatchTouchEvent_ ACTION_MOVE----------------")}MotionEvent.ACTION_UP-> {Log.e("mlt","---MyView---dispatchTouchEvent_ ACTION_UP----------------")}}return super.dispatchTouchEvent(ev)}@SuppressLint("ClickableViewAccessibility")override fun onTouchEvent(event: MotionEvent?): Boolean {when (event?.action) {MotionEvent.ACTION_DOWN -> {Log.e("mlt","---MyView---onTouchEvent ACTION_DOWN----------------")}MotionEvent.ACTION_MOVE -> {Log.e("mlt","---MyView---onTouchEvent ACTION_MOVE----------------")}MotionEvent.ACTION_UP-> {Log.e("mlt","---MyView---onTouchEvent ACTION_UP----------------")}}return super.onTouchEvent(event)}
}

触摸事件是从上往下传递的,因为最外层是activity,所以从这里开始传递

activity:

class OntouchTextActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_ontouch_text)}override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {when (ev?.action) {MotionEvent.ACTION_DOWN -> {Log.e("mlt","---OntouchTextActivity---dispatchTouchEvent_ ACTION_DOWN----------------")}MotionEvent.ACTION_MOVE -> {Log.e("mlt","---OntouchTextActivity---dispatchTouchEvent_ ACTION_MOVE----------------")}MotionEvent.ACTION_UP-> {Log.e("mlt","---OntouchTextActivity---dispatchTouchEvent_ ACTION_UP----------------")}}return super.dispatchTouchEvent(ev)}override fun onTouchEvent(event: MotionEvent?): Boolean {when (event?.action) {MotionEvent.ACTION_DOWN -> {Log.e("mlt","---OntouchTextActivity---onTouchEvent ACTION_DOWN----------------")}MotionEvent.ACTION_MOVE -> {Log.e("mlt","---OntouchTextActivity---onTouchEvent ACTION_MOVE----------------")}MotionEvent.ACTION_UP-> {Log.e("mlt","---OntouchTextActivity---onTouchEvent ACTION_UP----------------")}}return super.onTouchEvent(event)}}

xml布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".ontouch.OntouchTextActivity"><com.text.myscrolling.ontouch.MyViewGroupAandroid:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/teal_200"/><com.text.myscrolling.ontouch.MyViewGroupBandroid:layout_width="200dp"android:layout_height="200dp"android:background="@color/purple_500"tools:ignore="MissingConstraints" /><com.text.myscrolling.ontouch.MyViewandroid:layout_width="100dp"android:layout_height="100dp"android:background="@color/purple_200"tools:ignore="MissingConstraints" /></androidx.constraintlayout.widget.ConstraintLayout>

因为要达到上门的效果,是从A -> B-> myview 的,这里不知道上面的文章是否是这样的布局。

这里前面和上面的文章里面内容没有任何区别,事情的第一步开始是dispatchTouchEvent是否分发,这里都返回super 不做任何处理逻辑

这里看输入日志:

2021-06-19 17:07:50.569 29147-29147/com.text.myscrolling E/mlt: ---OntouchTextActivity---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:07:50.571 29147-29147/com.text.myscrolling E/mlt: ---MyView---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:07:50.571 29147-29147/com.text.myscrolling E/mlt: ---MyView---onTouchEvent ACTION_DOWN----------------
2021-06-19 17:07:50.571 29147-29147/com.text.myscrolling E/mlt: ---MyViewGroupB---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:07:50.571 29147-29147/com.text.myscrolling E/mlt: ---MyViewGroupB---onInterceptTouchEvent ACTION_DOWN----------------
2021-06-19 17:07:50.572 29147-29147/com.text.myscrolling E/mlt: ---MyViewGroupB---onTouchEvent ACTION_DOWN----------------
2021-06-19 17:07:50.572 29147-29147/com.text.myscrolling E/mlt: ---MyViewGroupA---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:07:50.572 29147-29147/com.text.myscrolling E/mlt: ---MyViewGroupA---onInterceptTouchEvent ACTION_DOWN----------------
2021-06-19 17:07:50.572 29147-29147/com.text.myscrolling E/mlt: ---MyViewGroupA---onTouchEvent ACTION_DOWN----------------
2021-06-19 17:07:50.572 29147-29147/com.text.myscrolling E/mlt: ---OntouchTextActivity---onTouchEvent ACTION_DOWN----------------
2021-06-19 17:07:50.637 29147-29147/com.text.myscrolling E/mlt: ---OntouchTextActivity---dispatchTouchEvent_ ACTION_UP----------------
2021-06-19 17:07:50.638 29147-29147/com.text.myscrolling E/mlt: ---OntouchTextActivity---onTouchEvent ACTION_UP----------------

开始是从activity 这里没错,最外层,这里点击的是myview最小的那块,并没有从myviewgroupA开始到MyviewgroupB 再到 MyView ,而是 挨着顺序来的,从activity -> myview -> myViewGroupB->myViewGroupA,这样一层一层来的,并不是和继承相关系,activity - viewgroup - view这样的传递顺序,而是和界面布局层级相关!这里不是知道对否,错了的就当什么都没有发生,一笑而过,大家可以自己实验一下,才能明白!这里区别感觉和其他人写的不一样,不知道这里是kotlin原因还是版本原因,这里是最高版本。这里就不画图了。

总结相当于一个环形,从哪里开始到哪里结束!!!

这里也对myviewGroupB做拦截操作,再MotionEvent.ACTION_DOWN 返回true但不做任何处理

日志:

2021-06-19 17:31:40.257 21447-21447/com.text.myscrolling E/mlt: ---OntouchTextActivity---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:31:40.258 21447-21447/com.text.myscrolling E/mlt: ---MyView---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:31:40.258 21447-21447/com.text.myscrolling E/mlt: ---MyView---onTouchEvent ACTION_DOWN----------------
2021-06-19 17:31:40.258 21447-21447/com.text.myscrolling E/mlt: ---MyViewGroupB---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:31:40.259 21447-21447/com.text.myscrolling E/mlt: ---MyViewGroupB---onInterceptTouchEvent ACTION_DOWN----------------
2021-06-19 17:31:40.259 21447-21447/com.text.myscrolling E/mlt: ---MyViewGroupB---onTouchEvent ACTION_DOWN----------------
2021-06-19 17:31:40.259 21447-21447/com.text.myscrolling E/mlt: ---MyViewGroupA---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:31:40.259 21447-21447/com.text.myscrolling E/mlt: ---MyViewGroupA---onInterceptTouchEvent ACTION_DOWN----------------
2021-06-19 17:31:40.259 21447-21447/com.text.myscrolling E/mlt: ---MyViewGroupA---onTouchEvent ACTION_DOWN----------------
2021-06-19 17:31:40.260 21447-21447/com.text.myscrolling E/mlt: ---OntouchTextActivity---onTouchEvent ACTION_DOWN----------------
2021-06-19 17:31:40.295 21447-21447/com.text.myscrolling E/mlt: ---OntouchTextActivity---dispatchTouchEvent_ ACTION_UP----------------
2021-06-19 17:31:40.295 21447-21447/com.text.myscrolling E/mlt: ---OntouchTextActivity---onTouchEvent ACTION_UP----------------

让人想不到的是没有任何作用,具体原因不明,既然这里无作用,那么再dispatchTouchEvent里面返回true呢,也是再Down里面:

日志:

2021-06-19 17:33:57.672 22275-22275/com.text.myscrolling E/mlt: ---OntouchTextActivity---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:33:57.673 22275-22275/com.text.myscrolling E/mlt: ---MyView---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:33:57.673 22275-22275/com.text.myscrolling E/mlt: ---MyView---onTouchEvent ACTION_DOWN----------------
2021-06-19 17:33:57.673 22275-22275/com.text.myscrolling E/mlt: ---MyViewGroupB---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:33:57.715 22275-22275/com.text.myscrolling E/mlt: ---OntouchTextActivity---dispatchTouchEvent_ ACTION_UP----------------
2021-06-19 17:33:57.716 22275-22275/com.text.myscrolling E/mlt: ---MyViewGroupB---dispatchTouchEvent_ ACTION_UP----------------
2021-06-19 17:33:57.716 22275-22275/com.text.myscrolling E/mlt: ---MyViewGroupB---onTouchEvent ACTION_UP----------------
2021-06-19 17:33:57.717 22275-22275/com.text.myscrolling E/mlt: ---OntouchTextActivity---onTouchEvent ACTION_UP----------------

这里有作用了,并且再myviewgroupB的这里,不会再执行viewgroupA了,然后再执行最外层的activity 的事件分发,如果没有处理,又到viewgroupB事情分发UP事件,再看自己需要处理吗?,如果没有处理再走activity的事件处理。

再一次实践,再myviewgroupB里面处理事件:

日志:

2021-06-19 17:44:37.245 25239-25239/com.text.myscrolling E/mlt: ---OntouchTextActivity---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:44:37.246 25239-25239/com.text.myscrolling E/mlt: ---MyView---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:44:37.246 25239-25239/com.text.myscrolling E/mlt: ---MyView---onTouchEvent ACTION_DOWN----------------
2021-06-19 17:44:37.247 25239-25239/com.text.myscrolling E/mlt: ---MyViewGroupB---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:44:37.293 25239-25239/com.text.myscrolling E/mlt: ---OntouchTextActivity---dispatchTouchEvent_ ACTION_UP----------------
2021-06-19 17:44:37.294 25239-25239/com.text.myscrolling E/mlt: ---MyViewGroupB---dispatchTouchEvent_ ACTION_UP----------------
2021-06-19 17:44:37.296 25239-25239/com.text.myscrolling E/mlt: ---MyViewGroupB---onTouchEvent ACTION_UP----------------
2021-06-19 17:44:37.298 25239-25239/com.text.myscrolling E/mlt: ---OntouchTextActivity---onTouchEvent ACTION_UP----------------

并没有任何变化,明明再onTouchEvent的ACTION_DOWN这里返回true了,有没有发现一个问题就是onTouchEvent里面ACTION_DOWN方法是没有执行了,因为这里没有移动所以不会自行ACTION_MOVE ,,但执行了ACTION_UP,那么再ACTION_UP里面返回true呢

old:

@SuppressLint("ClickableViewAccessibility")override fun onTouchEvent(event: MotionEvent?): Boolean {when (event?.action) {MotionEvent.ACTION_DOWN -> {Log.e("mlt","---MyViewGroupB---onTouchEvent ACTION_DOWN----------------")return true}MotionEvent.ACTION_MOVE -> {Log.e("mlt","---MyViewGroupB---onTouchEvent ACTION_MOVE----------------")}MotionEvent.ACTION_UP-> {Log.e("mlt","---MyViewGroupB---onTouchEvent ACTION_UP----------------")}}return super.onTouchEvent(event)}

new:

@SuppressLint("ClickableViewAccessibility")override fun onTouchEvent(event: MotionEvent?): Boolean {when (event?.action) {MotionEvent.ACTION_DOWN -> {Log.e("mlt","---MyViewGroupB---onTouchEvent ACTION_DOWN----------------")}MotionEvent.ACTION_MOVE -> {Log.e("mlt","---MyViewGroupB---onTouchEvent ACTION_MOVE----------------")}MotionEvent.ACTION_UP-> {Log.e("mlt","---MyViewGroupB---onTouchEvent ACTION_UP----------------")return true}}return super.onTouchEvent(event)}

日志:

2021-06-19 17:48:47.177 26495-26495/com.text.myscrolling E/mlt: ---OntouchTextActivity---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:48:47.178 26495-26495/com.text.myscrolling E/mlt: ---MyView---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:48:47.178 26495-26495/com.text.myscrolling E/mlt: ---MyView---onTouchEvent ACTION_DOWN----------------
2021-06-19 17:48:47.178 26495-26495/com.text.myscrolling E/mlt: ---MyViewGroupB---dispatchTouchEvent_ ACTION_DOWN----------------
2021-06-19 17:48:47.211 26495-26495/com.text.myscrolling E/mlt: ---OntouchTextActivity---dispatchTouchEvent_ ACTION_UP----------------
2021-06-19 17:48:47.212 26495-26495/com.text.myscrolling E/mlt: ---MyViewGroupB---dispatchTouchEvent_ ACTION_UP----------------
2021-06-19 17:48:47.212 26495-26495/com.text.myscrolling E/mlt: ---MyViewGroupB---onTouchEvent ACTION_UP----------------

看到变化了,因为myviewGroupB再ACTION_UP的时候自己消费了事件,没有再传递到activity了。

这里发现一个结论:如果再dispathTouchEvent里面ACTION_DOWN里面消费了,那么其他ontouchEvent的ACTIION_DOWM不会再执行了!!

今天先暂时讲到这里因为事件关系!!!

  相关解决方案