详细剖析 android onInterceptTouchEvent(MotionEvent event) 和 onTouchEvent(MotionEvent event) 的事件传递机制

搬家后的博客链接: IT客栈 www.itkezhan.org


最近遇到 添加 ScrollView 之后 某些组件的 onTouchEvent() 没有响应,现在我们来解剖一下android 对于这种事件的处理和内部的传递机制。



1.ViewGroup代表可以包含子组件的类,例如我们的(LinearLayout、TableLayout、ScrollView);

2.ChildView 代表不能包含其他组件的类 ,例如我们的(Button、TextView、EditText);


对于 ViewGroup 有包含  onInterceptTouchEvent(MotionEvent event)onTouchEvent(MotionEvent event)

而且 ChildView 只包含了  onTouchEvent(MotionEvent event)


如果有疑问的话可以去看一下 Button 和 TextView 的 API 里面确实查不到 onInterceptTouchEvent(MotionEvent event)


===============================================================================


为了大家更好理解我制作成图片了。


需要用到的源代码   MainActivity.java  myScroll.java(继承 ScrollView)  myLayout.java(继承 LinearLayout)   myText.java(继承 EditText)   activity_main.xml(布局文件)

//MainActivity.java
package com.example.lab;


import android.app.Activity;
import android.os.Bundle;


public class MainActivity extends Activity
{
	
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
	
}


//myScroll.java
package com.example.lab;

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

public class myScroll extends ScrollView
{

	
	public myScroll(Context context)
	{
		super(context);

	}

	public myScroll(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		
	}
	
	public myScroll(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);
	}
	
	@Override
	public boolean onInterceptTouchEvent(MotionEvent event) 
	{
		boolean b = super.onInterceptTouchEvent(event);
		Log.e("Info","Return " + b + " From myScroll OnInterceptTouchEvent" + "---" + "GetActionEvent:" + event.getActionMasked());
		return b;
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event)
	{

		boolean b = super.onTouchEvent(event);
		Log.e("Info","Return " + b + " From myScroll OnTouchEvent" + "---" + "GetActionEvent:" + event.getActionMasked());
		return b;
	}
}


//myLayout.java
package com.example.lab;

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
{

	public myLayout(Context context)
	{
		super(context);
	}
	
	public myLayout(Context context, AttributeSet attrs)
	{
		super(context, attrs);
	}
	
	public boolean onInterceptTouchEvent (MotionEvent event)
	{
		boolean b = super.onInterceptTouchEvent(event);
		Log.e("Info","Return " + b + " From myLayout OnInterceptTouchEvent" + "---" + "GetActionEvent:" + event.getActionMasked());
		return b;
	}
	
	public boolean onTouchEvent(MotionEvent ev)
	{
		boolean b = super.onTouchEvent(ev);;
		Log.e("Info","Return " + b + " From myLayout OnTouchEvent" + "---" + "GetActionEvent:" + ev.getActionMasked());
		return b;
	}
	
}


 
 
//myText.java
package com.example.lab;

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

public class myText extends EditText
{

	public myText(Context context)
	{
		super(context);
	}
	public myText(Context context, AttributeSet attrs)
	{
		super(context, attrs);
	}
	public myText(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event)
	{	
		boolean b = super.onTouchEvent(event);
		Log.e("Info","Return " + b + " From myText OnTouchEvent" + "---" + "GetActionEvent:" + event.getActionMasked());
		return b;
	}
}

avtivity_main.xml
<com.example.lab.myScroll xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.lab.myLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <com.example.lab.myText
            android:layout_width="match_parent"
        android:layout_height="match_parent"
            >
        </com.example.lab.myText>
        
    </com.example.lab.myLayout>

</com.example.lab.myScroll>


创建一个包名为 com.example.lab 然后把文件放到对应的地方就可以了运行了。


===========================================================================


有了源码,来说一下机制吧。

上面的布局文件  scroll 在最外层  layout 在中间  最里面的 text  如下面 这张图片


  

当我们触发屏幕事件的时候(点击屏幕、手指在屏幕上移动) 事件的传播流程是这样的。

如果 onInterceptTouchEvent()  返回的是 false(说明事件会传递下去),这里可以把  onInterceptTouchEvent() 看成是守门人,当它返回 false 的时候,证明目前这个类的 onTouchEvent 不是用来处理这个事件的,事件继续向内传播,如果返回 true 则由本类的onTouchEvent 进行处理,并停止事件的传播


制作这张图,看起来可能会直观一点。




其实onInterceptTouchEvent() 就是判断事件,OntouchEvent()就是处理事件。


技术在于交流,如有不懂请留言。我的QQ 1396686515;






你可能感兴趣的:(详细剖析 android onInterceptTouchEvent(MotionEvent event) 和 onTouchEvent(MotionEvent event) 的事件传递机制)