`
king_tt
  • 浏览: 2234036 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

详解onInterceptTouchEvent和onTouchEvent之间的关系

阅读更多

过完今天就放假了,哇哈哈,提前祝大家端午快乐,多吃粽子,公司给我们发了几个粽子,今天早上吃了个,还不错,呵呵,回到正题...之前在网上看了很多这方面的文章,有的写得很不错,然后我也决定自己也写一篇这样子的文章,一是加深理解onInterceptTouchEvent和onTouchEvent之间的关系,二是希望大家看到我写得东西能少走些弯路,本人的语文也不是很好,语文是数学老师教的,每次写文章也是跟着感觉走,呵呵

1.onInterceptTouchEvent(),Intercept 阻断,打断的意思,顾名思义这个方法是阻断TouchEvent的传递,这个方法返回值是false或者true,也许很多不了解的人就会问,阻断TouchEvent的传递是什么意思?onInterceptTouchEvent()这个方法是ViewGroup里面的方法,一个ViewGroup里面可以包含很多的ViewGroup、View,然后ViewGroup里面的View想要获得TouchEvent的话,必须是从ViewGroup传递过来的,而onInterceptTouchEvent方法就是拦截TouchEvent的,顾名思义,当onInterceptTouchEvent返回false的时候,子View就有TouchEvent,返回true的时候,子View的TouchEvent就被拦截了,TouchEvent就给ViewGroup处理,子View就没有TouchEvent

2.onTouchEvent()用于处理事件(重点onTouch这个事件是从子控件回传到父控件的,一层层向上传),返回值决定当前控件是否消费(consume)了这个事件,也就是说在当前控件在处理完Touch事件后,是否还允许Touch事件继续向上(父控件)传递。
返回false,则向上传递给父控件,详细一点就是这个touch事件就给了父控件,那么后面的up事件就是到这里touch触发,不会在传给它的子控件。如果父控件依然是false,那touch的处理就给到父控件的父控件,那么up的事件处理都在父控件的父控件,不会触发下面的。
返回true,如果是子控件返回true,那么它的touch事件都在这里处理,父控件是处理不了,因为它收不到子控件传给他的touch,被子控件给拦截了
(注:可能你会觉得是否消费了有关系吗,反正我已经针对事件编写了处理代码?答案是有区别!比如ACTION_MOVE或者ACTION_UP发生的前提是一定曾经发生了ACTION_DOWN,如果你没有消费ACTION_DOWN,那么系统会认为ACTION_DOWN没有发生过,所以ACTION_MOVE或者ACTION_UP就不能被捕获。)

下面我们结合例子来深刻理解下这两者之间的关系

1.首先我们新建一个MyLayout继承LinearLayout,我们知道onInterceptTouchEvent()是ViewGroup里面的方法,我们不直接去继承ViewGroup而是继承ViewGroup的一个导出类(子类),然后重写onInterceptTouchEvent和onTouchEvent这两个方法,onInterceptTouchEvent默认情况下返回false,即不拦截TouchEvent,onTouchEvent默认返回false,即ViewGroup默认不消费TouchEvent

 

package com.example.ontouchactivity;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class MyLayout extends LinearLayout {
	private static final String TAG = "OnTouch";

	public MyLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		Log.e(TAG, "MyLayout----onInterceptTouchEvent");
		return super.onInterceptTouchEvent(ev);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			Log.e(TAG, "MyLayout----DOWN");
			break;
		case MotionEvent.ACTION_UP:
			Log.e(TAG, "MyLayout----UP");
			break;
		}
		return super.onTouchEvent(event);
	}
}

 

然后布局文件,在MyLayout里面嵌套一个TextView

 

 <com.example.ontouchactivity.MyLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent" >
     
     <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello_world" />

 </com.example.ontouchactivity.MyLayout>

MainActivity如下

 

 

package com.example.ontouchactivity;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.TextView;

public class MainActivity extends Activity {
	private static final String TAG = "OnTouch";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		TextView mTextView = (TextView) findViewById(R.id.text);
		mTextView.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					Log.i(TAG, "TextView----DOWN");
					break;
				case MotionEvent.ACTION_UP:
					Log.i(TAG, "TextView----UP");
					break;
				}
				return false;
			}
		});
	}


}

1.默认情况下,我们触摸下屏幕看下打印

 


传递顺序:MyLayout---->TextView----->MyLayout,因为onInterceptTouchEvent默认情况下返回false,即不拦截TouchEvent,所以将TouchEvent传递给TextView,而TextView返回false,即没有消费TouchEvent,没有消费就将TouchEvent向上传递给MyLayout,而MyLayout的onTouchEvent默认情况下返回是false,即也是不消费TouchEvent,所以我们看到如上的打印

2.将MyLayout的onInterceptTouchEvent返回值修改为true,拦截TouchEvent,看下打印输出


传递顺序:MyLayout----->MyLayout,我们看到TouchEvent并没有传递给TextView,而是被MyLayout给拦截了,拦截之后MyLayout会将TouchEvent传给自己,

MyLayout的onTouchEvent默认情况下返回是false,即不消费TouchEvent,所以我们看到如上的打印

3.将MyLayout的onInterceptTouchEvent返回值修改为true,拦截TouchEvent,将MyLayout的onTouchEvent返回值修改为true看下打印输出


传递顺序:MyLayout----->MyLayout---->MyLayoutTouchEvent被MyLayout给拦截了,TouchEvent传递给自己,而onTouchEvent返回值为true,即自己消费TouchEvent,所以我们看到如上的打印

4.将MyLayout的onInterceptTouchEvent返回值修改为false,将TextView的Ontouch的返回值修改为true, MyLayout的onTouchEvent返回值false 或者 true 都无所谓,看下打印输出


传递顺序:按下MyLayout----->TextView,抬起MyLayout----->TextView,因为按下时MyLayout将TouchEvent传递给TextView,而TextView返回true,消费了TouchEvent,消费了TouchEvent就不向上传给MyLayout了,抬起也是一样

大概就是这个意思,不知道按照我思路写的文章大家看不看得懂,呵呵,写的有错误的地方还希望大家指出,谢谢

分享到:
评论

相关推荐

    onInterceptTouchEvent和onTouchEvent调用关系详解

    理解并掌握`onInterceptTouchEvent`和`onTouchEvent`的调用关系,可以帮助开发者更灵活地控制触摸事件的流向,实现复杂的手势识别和用户界面交互。在实际开发中,我们可以通过重写这两个方法,为自定义View或...

    浅谈Android onTouchEvent 与 onInterceptTouchEvent的区别详解

    在Android开发中,触摸事件的处理是用户交互的基础,而`onTouchEvent`和`onInterceptTouchEvent`则是处理这些事件的关键方法。这篇文章将深入解析这两个方法的区别和它们在触摸事件处理链中的作用。 首先,`...

    Android中touch事件传递测试demo

    onInterceptTouchEvent和onTouchEvent调用时序详解 测试demo 详细介绍请移步:http://blog.csdn.net/yiranxinshou/article/details/9201833

    dispatch、onIntercept、onTouch三者对MotionEvent的分发、拦截机制Demo

    Title : dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent三者对MotionEvent的分发、拦截机制分析 Author: yaong Category:自己做的Demo Tips : 三个自定义View,依次嵌套,并各自覆写拦截、监听方法,通过...

    Android控件架构与自定义控件详解(四)——事件拦截机制分析

    Android事件分发分为三个步骤:dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent。 1. dispatchTouchEvent:事件首先由根ViewGroup接收到,然后向下分发。每个ViewGroup都有机会拦截或传递事件。 2. ...

    详解Android事件的分发、拦截和执行

    Android的触摸事件分发过程由三个很重要的方法来共同完成:dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent。我先将这三个方法大体的介绍一下。  •public boolean dispatchTouchEvent(MotionEvent ev)...

    Android 35 道面试题及答案.docx

    Android 中的 View 有一个分发机制,包括 dispatchTouchEvent、onInterceptTouchEvent 和 onTouchEvent 三个方法。dispatchTouchEvent 是用于分发事件的入口,onInterceptTouchEvent 是用于拦截事件,onTouchEvent ...

    高级布局篇1

    - 事件拦截与派发方案,通过重写onInterceptTouchEvent和onTouchEvent来处理滑动事件。 - 基于NestingScrolling机制,利用NestedScrollView和NestedScrollingChild接口。 - 基于CoordinatorLayout和Behavior,...

    下拉上拉刷新Android-PullToRefresh-1.2.1.zip

    PullToRefresh库通过覆写ViewGroup的onInterceptTouchEvent和onTouchEvent方法,捕获并处理滑动事件。当用户下拉到一定距离时,显示刷新指示器,并启动刷新逻辑。同样,上拉加载更多也是监听上拉手势,触发加载新...

    Android事件处理机制详解及源码

    这一过程涉及到了`dispatchTouchEvent()`、`onInterceptTouchEvent()`和`onTouchEvent()`三个关键方法。 1. `dispatchTouchEvent()`:这是每个View都有的方法,用于分发触摸事件。系统首先调用此方法,将事件传递给...

    andorid 各种view的详解 完整代码

    10. **触控事件分发**:在`ViewGroup`中,触控事件会按照`onInterceptTouchEvent()`和`onTouchEvent()`的顺序分发。通过重写这些方法,可以实现自定义的事件处理逻辑。 总之,`Android`的`View`系统是构建用户界面...

    GreedyViews:一些 ViewLayout 类重写了它们的 super 的 onInterceptTouchEvent() 实现,以防止将触摸事件传递到它们的内部视图

    2. **`onInterceptTouchEvent()`详解**: 这个方法允许父View在子View之前有机会处理触摸事件。默认情况下,`onInterceptTouchEvent()`返回`false`,表示父View不拦截事件,事件将继续传递。若返回`true`,则表示父...

    Android事件的分发机制详解

    事件分发主要涉及三个关键方法:`onTouchEvent()`, `onInterceptTouchEvent()` 和 `dispatchTouchEvent()`。首先,事件由系统发送到最顶层的ViewGroup,然后逐级向下分发。在分发过程中,`dispatchTouchEvent()` ...

    Android开发之无痕过渡下拉刷新控件的实现思路详解

    事件分发主要涉及三个方法:`dispatchTouchEvent`、`onInterceptTouchEvent`和`onTouchEvent`。通常,事件首先由Activity处理,然后传递给Window,最后到达View。如果View不处理事件,事件会回传给上一级处理。`...

    ViewPagerDemo

    这可以通过重写ViewPager的`onInterceptTouchEvent()`和`onTouchEvent()`方法来实现。首先,在`onInterceptTouchEvent()`中返回`false`,阻止事件传递给子View;然后在`onTouchEvent()`中同样返回`false`,确保...

    Android自定义组件开发

    - **事件传递机制**:理解`dispatchTouchEvent()`, `onInterceptTouchEvent()`, `onTouchEvent()`之间的关系,以及如何拦截和处理触摸事件。 - **多点触控**:支持多指触摸操作,如缩放、旋转等,可以使用`...

    Android事件分发机制的详解

    这个过程是通过onTouchEvent和onInterceptTouchEvent两个方法来实现的。 事件的处理是指事件被处理的过程。在这个阶段,事件已经被某个View处理,View可以根据需要对事件进行处理,例如响应点击事件、滚动事件等。...

    Android事件处理机制ViewGroup的事件传递

    事件分发主要由`dispatchTouchEvent()`、`onInterceptTouchEvent()`和`onTouchEvent()`三个方法构成。当触摸事件发生时,事件首先传递到`ViewGroup`,`ViewGroup`有机会拦截这个事件,如果选择不拦截,则事件会继续...

    DragRankSquare.zip

    在DraggableLayout中,我们可以重写onLayout()方法来确定每个子View的位置,同时覆写onInterceptTouchEvent()和onTouchEvent()方法,实现对触摸事件的拦截和处理。在onInterceptTouchEvent()中,我们决定是否将事件...

Global site tag (gtag.js) - Google Analytics