view事件传递机制,在很多面试中会问道,我曾经也被问道,却没有回答上来。

写这篇博客前参考了https://blog.csdn.net/zuguorui/article/details/76862816。在这里感谢该作者,写的很详细。

今天我在这里写了一个demo去理解这个view的事件传递机制。

首先这个view包括两种,viewGroup和普通view。viewGroup就是里面还可以包含子控件的那种,如LinearLayout,ViewPager;view是指不能包含子view的那种,如Button,TextView,ImageView 等。

viewGroup的view传递事件按顺序是:

dispatchTouchEvent(分发)
onInterceptTouchEvent(拦截)
onTouchEvent(触摸)

view的事件传递顺序是

dispatchTouchEvent(分发)
onTouchEvent(触摸)

两者结合的一般顺序是

如果子控件没有消费掉触摸事件

viewPager: dispatchTouchEvent
viewPager: onInterceptTouchEvent
myImageView: dispatchTouchEvent
myImageView: onTouchEvent
viewPager: onTouchEvent

如果子控件消费掉触摸事件,比如执行了onClick方法,执行完onClick后,就不会再执行父控件的onTouchEvent

viewPager: dispatchTouchEvent
viewPager: onInterceptTouchEvent
myImageView: dispatchTouchEvent
myImageView: onTouchEvent
myImageView: onclick

如果onInterceptTouchEvent 返回true,则父控件消费触摸事件

如果onInterceptTouchEvent 返回false,则子控件消费触摸事件

我们来写demo看看,这个机制到底是怎么实现的。我使用viewPage和image做的测试。

我自己测试发现一个有趣的事情,

1、onInterceptTouchEvent 不做任何修改,

return super.onInterceptTouchEvent(ev)

a 子view的onTouchEvent 不做任何修改

     return super.onTouchEvent(event);

如果子view不消费onTouchEvent 事件,则一次滑动中,父控件不会多次调用onInterceptTouchEvent

09-13 16:55:21.427 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 16:55:21.428 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: onInterceptTouchEvent
09-13 16:55:21.429 6089-6089/ylj.com.vieweventapplication E/view_event_myImageView: dispatchTouchEvent
09-13 16:55:21.429 6089-6089/ylj.com.vieweventapplication E/view_event_myImageView: onTouchEvent
09-13 16:55:21.429 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent
09-13 16:55:21.438 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 16:55:21.438 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent
09-13 16:55:21.452 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 16:55:21.452 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent
09-13 16:55:21.460 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 16:55:21.460 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent
09-13 16:55:21.468 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 16:55:21.468 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent
09-13 16:55:21.476 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 16:55:21.477 6089-6089/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent

b 如果子控件onTouchEvent 返回true,view group 则会多次调用onInterceptTouchEvent。

09-13 17:12:47.652 7371-7371/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 17:12:47.652 7371-7371/ylj.com.vieweventapplication E/view_event_viewPager: onInterceptTouchEvent
09-13 17:12:47.652 7371-7371/ylj.com.vieweventapplication E/view_event_myImageView: dispatchTouchEvent
09-13 17:12:47.652 7371-7371/ylj.com.vieweventapplication E/view_event_myImageView: onTouchEvent
09-13 17:12:47.727 7371-7371/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 17:12:47.727 7371-7371/ylj.com.vieweventapplication E/view_event_viewPager: onInterceptTouchEvent
09-13 17:12:47.727 7371-7371/ylj.com.vieweventapplication E/view_event_myImageView: dispatchTouchEvent
09-13 17:12:47.727 7371-7371/ylj.com.vieweventapplication E/view_event_myImageView: onTouchEvent
09-13 17:12:47.738 7371-7371/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 17:12:47.738 7371-7371/ylj.com.vieweventapplication E/view_event_viewPager: onInterceptTouchEvent
09-13 17:12:47.738 7371-7371/ylj.com.vieweventapplication E/view_event_myImageView: dispatchTouchEvent
09-13 17:12:47.738 7371-7371/ylj.com.vieweventapplication E/view_event_myImageView: onTouchEvent
09-13 17:12:47.760 7371-7371/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 17:12:47.760 7371-7371/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent
09-13 17:12:47.776 7371-7371/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 17:12:47.776 7371-7371/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent
09-13 17:12:47.777 7371-7371/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 17:12:47.777 7371-7371/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent
2、onInterceptTouchEvent 返回true

输出如下,不会调用子view的方法

09-13 16:52:34.841 4478-4478/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 16:52:34.841 4478-4478/ylj.com.vieweventapplication E/view_event_viewPager: onInterceptTouchEvent
09-13 16:52:34.842 4478-4478/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent
09-13 16:52:34.848 4478-4478/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 16:52:34.848 4478-4478/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent
09-13 16:52:34.864 4478-4478/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 16:52:34.864 4478-4478/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent
09-13 16:52:34.871 4478-4478/ylj.com.vieweventapplication E/view_event_viewPager: dispatchTouchEvent
09-13 16:52:34.871 4478-4478/ylj.com.vieweventapplication E/view_event_viewPager: onTouchEvent

3、onInterceptTouchEvent 返回false,子view的onTouchevent

return super.onTouchEvent(event);

这个时候,viewPager 可以滑动

3、onInterceptTouchEvent 返回false,子view的onTouchevent

return true;

这个时候,viewPager 就不能滑动了

测试源码如下,复写的viewPager

package ylj.com.vieweventapplication;import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;/*** Created by dfgx_yinlijuan on 2018/9/13.10:06*/public class MyViewPager extends ViewPager {String tag="viewPager";public MyViewPager(@NonNull Context context) {super(context);}public MyViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {super(context, attrs);}@Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {Tools.log(tag,"dispatchTouchEvent");return super.dispatchTouchEvent(ev);}@Overridepublic boolean onTouchEvent(MotionEvent ev) {Tools.log(tag,"onTouchEvent");return super.onTouchEvent(ev);}@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {Tools.log(tag,"onInterceptTouchEvent");return super.onInterceptTouchEvent(ev);
//        return false;}
}

复写的ImageView

package ylj.com.vieweventapplication;import android.content.Context;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;/*** Created by dfgx_yinlijuan on 2018/9/13.14:49*/public class MyImageView extends android.support.v7.widget.AppCompatImageView {String tag="myImageView";public MyImageView(Context context) {super(context);}public MyImageView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}public MyImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overridepublic boolean dispatchTouchEvent(MotionEvent event) {Tools.log(tag,"dispatchTouchEvent");return super.dispatchTouchEvent(event);}@Overridepublic boolean onTouchEvent(MotionEvent event) {Tools.log(tag,"onTouchEvent");return super.onTouchEvent(event);
//        return true;}}

activity 调用

package ylj.com.vieweventapplication;import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;import java.util.ArrayList;
import java.util.List;/*** view 事件传递机制demo*/
public class ViewEventActivty extends AppCompatActivity {final String tag = "button";ViewPager viewPager;List<View> views=new ArrayList<>();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.actvity_view_event);MyViewPager viewPager = (MyViewPager) findViewById(R.id.viewPager);//        viewPager.setAdapter(new GuidePageAdapter());for (int i = 0; i < 3; i++) {MyImageView imageView = new MyImageView(this);if (i == 0) {imageView.setBackgroundColor(Color.RED);} else if (i == 1) {imageView.setBackgroundColor(Color.GREEN);} else if (i == 2) {imageView.setBackgroundColor(Color.BLUE);}imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));views.add(imageView);}GuideAdapter adapter = new GuideAdapter(views);viewPager.setAdapter(adapter);}class GuideAdapter extends PagerAdapter {List<View> mViews;GuideAdapter(List<View> views) {this.mViews = views;}@Overridepublic int getCount() {return mViews.size();}@Overridepublic boolean isViewFromObject(@NonNull View view, @NonNull Object object) {return view==object;}@Overridepublic void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {((ViewPager) container).removeView(mViews.get(position));}@Overridepublic Object instantiateItem(@NonNull ViewGroup container, int position) {((ViewPager)container).addView(mViews.get(position));return mViews.get(position);}}
}

Android View事件传递机制相关推荐

  1. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  2. Android Touch事件传递机制 二:单纯的(伪生命周期) 这个清楚一点

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

  3. Android Touch事件传递机制 二:单纯的(伪生命周期)

    转载于:http://blog.csdn.net/yuanzeyao/article/details/38025165 在前一篇文章中,我主要讲解了Android源码中的Touch事件的传递过程,现在 ...

  4. Android之Android触摸事件传递机制

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/53431274 本文出自:[顾林海的博客] ##前言 关于Android ...

  5. Android中事件传递机制的总结

    事件传递虽然算不上某个单独的知识点,但是在实际项目开发中肯定会碰到,如果不明白其中的原理,那在设计各种滑动效果时就会感到很困惑. 关于事件的传递,我们可能会有以下疑问: 事件是如何传递的 事件是如何处 ...

  6. Android Touch事件传递机制解析 (推荐)

    最近新闻列表里的下拉 down up  move 等等让我十分头疼 ,无意间看到了一篇非常不错的帖子,转载如下: 开篇语:最近程序在做一个小效果,要用到touch,结果整得云里面雾里的,干脆就好好把a ...

  7. Android View 事件分发机制详解

    想必很多android开发者都遇到过手势冲突的情况,我们一般都是通过内部拦截和外部拦截法解决此类问题.要想搞明白原理就必须了解View的分发机制.在此之前我们先来了解一下以下三个非常重要的方法: di ...

  8. android方向触摸事件,Android触摸事件传递机制,这一篇就够了

    整个触摸事件牵涉到的是,Activity,View,ViewGroup三者的传递机制. 这个触摸事件就是从外层往内层一层层的传递. 整个传递机制,分为3个步骤:分发,拦截,和消费. 1. 触摸事件的类 ...

  9. Android onTouch事件传递机制

    Android onTouch事件介绍: Android的触摸事件:onClick, onScroll, onFling等等,都是由许多个Touch组成的.其中Touch的第一个状态肯定是ACTION ...

  10. 一文读懂Android View事件分发机制

    Android View 虽然不是四大组件,但其并不比四大组件的地位低.而View的核心知识点事件分发机制则是不少刚入门同学的拦路虎.ScrollView嵌套RecyclerView(或者ListVi ...

最新文章

  1. Android 解析 Unable to add window is your activity running?
  2. mysql batch insert 遇到错误跳过_mysql 主从复制错误如何跳过
  3. centos安装python3小白_Centos7 安装Python3
  4. 剑指offer 翻转链表
  5. python列表写入csv文件_将多个列表写入csv。Python中的文件
  6. 嵌入式串口打印信息重定向到当前终端界面
  7. WSGI Application/Framework
  8. 13种常用按钮、文本框、表单等CSS样式
  9. 在matlab中产生dsp程序学习
  10. Android Studio欢迎界面和登陆界面的设计(小白)
  11. html轮播图片不显示不了,图片轮播的奇怪现象【图片显示不完整】
  12. python数据拟合之scipy.optimize.curve_fit
  13. V4.0系列软件如何替换授权文件
  14. ansible meta目录
  15. java 弹幕 原理_Flutter 实现虎牙/斗鱼 弹幕效果
  16. 数据变现四大模式释放电信大数据价值
  17. kubeadm部署k8s集群最全最详细
  18. 《计算机网络(谢希仁6版)》学习笔记(word导入)[待补全]
  19. Akka是个什么鬼?
  20. Java时间处理(UTC时间和本地时间转换)

热门文章

  1. 浅谈外存分配的几种方式
  2. Redis数据结构之集合对象
  3. 百度贴吧个人主页_回望人人网/新浪博客/百度贴吧时
  4. 移动终于又重新放出了8元套餐
  5. FPGA(3)--VHDL及原理图--4位全加器
  6. 验证信用卡c语言,信用卡卡号验证算法
  7. Github和Git是啥意思?下面来简单了解下。
  8. 解决“npm WARN requires a peer of XXX“问题
  9. 抖音培训教程,抖音培训班,抖音培训课程(2019实时更新中) -
  10. 提交代码到gitbub.com