android 触摸事件传递机制
来源:互联网 发布:淘宝买衣服怎么看质量 编辑:程序博客网 时间:2024/04/29 03:33
先运行拦截事件oninterceptTouchEvent(),再运行触摸事件onTouchEvent。
点击事件从上层到下层,事件回馈从下层到上层。
Android系统中的每个View的子类都具有下面三个和TouchEvent处理密切相关的方法:
1)publicboolean dispatchTouchEvent(MotionEvent ev) 这个方法用来分发TouchEvent
2)publicboolean onInterceptTouchEvent(MotionEvent ev) 这个方法用来拦截TouchEvent
3)publicboolean onTouchEvent(MotionEvent ev) 这个方法用来处理TouchEvent。
当TouchEvent发生时,首先Activity将TouchEvent事件通过dispatchTouchEvent方法传递给ViewGroup
1,ViewGroup通过dispatchTouchEvent方法传递给interceptTouchEvent:
(1)如果interceptTouchEvent返回true ,则交给这个ViewGroup的onTouchEvent处理。
(2)如果interceptTouchEvent返回false,则交给子View的 dispatchTouchEvent方法处理。
2,事件传递到子view 的 dispatchTouchEvent方法中,通过该方法传递到当前View的onTouchEvent方法中:
(1)如果onTouchEvent返回true,那么这个事件就会止于该view。
(2)如果onTouchEvent返回false ,那么这个事件会从这个子view 往上传递,而且都是传递到父View的onTouchEvent 来接收。 (3)如果传递到ViewGroup的 onTouchEvent 也返回false 的话,则继续传递到Activity的onTouchEvent中,如果还是false,则这个事件就会“消失“;
事件向上传递到中间的任何onTouchEvent方法中,如果返回true,则事件被消费掉,不会再传递。
在默认的onInterceptTouchEvent()方法和onTouchEvent()中返回值都是false。
代码示例:用两个LinearLayout模拟父View和子View:
布局xml:父view是FirstLayout,子View是SecondLayout。
<?xml version="1.0" encoding="utf-8"?><com.cindy.usingtouchevent.FirstLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.cindy.usingtouchevent.MainActivity"> <com.cindy.usingtouchevent.SecondLayout android:layout_width="match_parent" android:layout_height="match_parent"> </com.cindy.usingtouchevent.SecondLayout></com.cindy.usingtouchevent.FirstLayout>
FirstLayout.java
package com.cindy.usingtouchevent;import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.widget.LinearLayout;/** * Created by yub on 2016/10/9. */public class FirstLayout extends LinearLayout{ public FirstLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch(ev.getAction()){ case MotionEvent.ACTION_DOWN: showLog("onInterceptTouchEvent down"); break; case MotionEvent.ACTION_MOVE: showLog("onInterceptTouchEvent move"); break; case MotionEvent.ACTION_UP: showLog("onInterceptTouchEvent up"); break; default:break; }// return super.onInterceptTouchEvent(ev); **return false;** } @Overridepublic boolean dispatchTouchEvent(MotionEvent ev) { showLog("dispatchTouchEventok"); returnsuper.dispatchTouchEvent(ev);} @Override public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_DOWN: showLog("onTouchEvent down"); break; case MotionEvent.ACTION_MOVE: showLog("onTouchEvent move"); break; case MotionEvent.ACTION_UP: showLog("onTouchEvent up"); break; default:break; } **return false;** } private void showLog(String str){ System.out.println("FirstLinearLayout:"+str); }}
SecondLayout.java
public class SecondLayout extends LinearLayout { public SecondLayout(Context context,AttributeSetattrs) { super(context, attrs); } @Override public booleanonInterceptTouchEvent(MotionEventev) { switch(ev.getAction()){ case MotionEvent.ACTION_DOWN: showLog("onInterceptTouchEventdown"); break; case MotionEvent.ACTION_MOVE: showLog("onInterceptTouchEventmove"); break; case MotionEvent.ACTION_UP: showLog("onInterceptTouchEventup"); break; default:break; } **return true;** } @Override public boolean dispatchTouchEvent(MotionEventev){ showLog("dispatchTouchEventok"); return super.dispatchTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEventevent) { switch(event.getAction()){ case MotionEvent.ACTION_DOWN: showLog("onTouchEventdown"); break; case MotionEvent.ACTION_MOVE: showLog("onTouchEventmove"); break; case MotionEvent.ACTION_UP: showLog("onTouchEventup"); break; default:break; } **return true;** } private void showLog(String str){ System.out.println("SecondLinearLayout:"+ str); }}
MainActivity.java
public class MainActivity extends AppCompatActivity { private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); }}
Log分析
请注意代码中用**标注的返回值。
First dispatchTouchEvent();———-A事件
First onInteruptTouchEvent();————B事件
First TouchEvent();————C事件
Second dispatchTouchEvent();———–D事件
Second onInteruptTouchEvent();————-E事件
Second TouchEvent();—————F事件
1.ABC均返回true,此时log如下:
10-11 23:31:35.750 12434-12434/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:dispatchTouchEvent ok
事件不再分发。
2.A返回false,BC均返回true,log如下:
10-11 23:33:00.995 14165-14165/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:dispatchTouchEvent ok
10-11 23:33:00.995 14165-14165/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onInterceptTouchEvent down
10-11 23:33:00.995 14165-14165/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onTouchEvent down
10-11 23:33:01.010 14165-14165/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:dispatchTouchEvent ok
10-11 23:33:01.010 14165-14165/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onTouchEvent up
可以看出:首先执行A事件,传给拦截事件,传给触摸事件,再次分发,传给触摸事件,up后事件完成。
3.AC返回false,B返回true,log如下:
10-11 23:35:57.580 16818-16818/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:dispatchTouchEvent ok
10-11 23:35:57.580 16818-16818/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onInterceptTouchEvent down
10-11 23:35:57.580 16818-16818/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onTouchEvent down
可以看出:首先执行分发事件,传给拦截事件,传给触摸事件,触摸事件返回false,事件消失。
4.AB返回false,C返回true。此时事件会向子View传递。D返回true。log如下:
10-11 23:40:32.295 21737-21737/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:dispatchTouchEvent ok
10-11 23:40:32.295 21737-21737/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onInterceptTouchEvent down
10-11 23:40:32.295 21737-21737/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:dispatchTouchEvent ok
10-11 23:40:32.350 21737-21737/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:dispatchTouchEvent ok
10-11 23:40:32.350 21737-21737/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onInterceptTouchEvent up
可以看出:父分发–父拦截down–子分发–父分发–父拦截up,事件结束。
5.AB返回false,C返回true。D返回false,E,F返回true.Log如下:
10-11 23:44:11.895 25623-25623/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:dispatchTouchEvent ok
10-11 23:44:11.895 25623-25623/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onInterceptTouchEvent down
10-11 23:44:11.895 25623-25623/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:dispatchTouchEvent ok
10-11 23:44:11.895 25623-25623/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:onInterceptTouchEvent down
10-11 23:44:11.895 25623-25623/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:onTouchEvent down
10-11 23:44:11.900 25623-25623/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:dispatchTouchEvent ok
10-11 23:44:11.900 25623-25623/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onInterceptTouchEvent up
10-11 23:44:11.900 25623-25623/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:dispatchTouchEvent ok
10-11 23:44:11.900 25623-25623/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:onTouchEvent up
可以看出:父分发–父拦截down-子分发-子拦截down-子触摸down-子触摸up,事件结束。
6.AB返回false,C返回true。DE返回false,F返回true。log如下:
10-11 23:47:27.385 28570-28570/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:dispatchTouchEvent ok
10-11 23:47:27.390 28570-28570/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onInterceptTouchEvent down
10-11 23:47:27.390 28570-28570/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:dispatchTouchEvent ok
10-11 23:47:27.390 28570-28570/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:onInterceptTouchEvent down
10-11 23:47:27.390 28570-28570/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:onTouchEvent down
10-11 23:47:27.430 28570-28570/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:dispatchTouchEvent ok
10-11 23:47:27.430 28570-28570/com.cindy.usingtouchevent I/System.out: FirstLinearLayout:onInterceptTouchEventup
10-11 23:47:27.430 28570-28570/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:dispatchTouchEvent ok
10-11 23:47:27.430 28570-28570/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:onTouchEvent up
可以看出:父分发-父拦截down-子分发down-子拦截down-子触摸down-子触摸up,事件结束。
由5.6得知,子拦截的返回值与事件传播没有关系。
7.AB返回false,C返回true。DEF都返回false,log如下:
10-11 23:59:47.725 3738-3738/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:dispatchTouchEvent ok
10-11 23:59:47.725 3738-3738/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onInterceptTouchEvent down
10-11 23:59:47.725 3738-3738/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:dispatchTouchEvent ok
10-11 23:59:47.725 3738-3738/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:onInterceptTouchEvent down
10-11 23:59:47.725 3738-3738/com.cindy.usingtouchevent I/System.out:SecondLinearLayout:onTouchEvent down
10-11 23:59:47.725 3738-3738/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onTouchEvent down
10-11 23:59:47.755 3738-3738/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:dispatchTouchEvent ok
10-11 23:59:47.755 3738-3738/com.cindy.usingtouchevent I/System.out:FirstLinearLayout:onTouchEvent up
可以看出:父分发–父拦截-子分发-子拦截-子触摸–传回父级触摸事件down–父触摸up-事件结束。
- Android 触摸事件传递机制
- Android 触摸事件传递机制
- Android 触摸事件传递机制
- Android 触摸事件传递机制
- Android 触摸事件传递机制
- Android 触摸事件传递机制
- android 触摸事件传递机制
- android触摸事件传递机制
- Android 触摸事件传递机制
- Android触摸事件传递机制
- Android触摸事件传递机制
- Android 触摸事件传递机制
- Android 触摸事件传递机制
- 关于android触摸事件传递机制
- Android View 触摸事件传递机制
- Android ViewGroup 触摸事件传递机制
- Android触摸事件传递机制学习笔记
- Android View触摸事件传递机制
- 将pb 写到 buff中 或者从buffer中读到pb中
- 基于ViewPager封装轮播图控件
- 整理android开发的心情
- C#设计模式之代理模式(Proxy Pattern)
- Windows 10 与 CentOS 7 UFEI 双系统(双硬盘)总结
- android 触摸事件传递机制
- 3min初识ListView(2)-getView和convertView
- React Native 开发基础组件 触摸组件 类似于android原生 button
- OGNL中的#%$
- textView代码设置文字居中失效 textView设置文字居中两种方法
- 补10.9
- 读书-如何求解问题-现代启发式方法
- Unity连接Photo服务器搭建环境
- 我了解的开源网站和图片压缩网站