您的位置:首页 > 移动开发 > Android开发

android菜鸟之路-事件分发机制总结(二)

2016-01-07 09:23 543 查看


ViewGroup事件分发机制

自定义一个LinearLayout,ImageView和Button,小二,上代码
<LinearLayout 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"
tools:context=".MainActivity" >
<com.example.aaaaa.MyLinear
android:id="@+id/linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#956456"
>
<com.example.aaaaa.MyImage
android:id="@+id/id_ll"
android:layout_width="150dp"
android:layout_height="150dp"
android:src="@drawable/ic_launcher"
android:text="click me" />
<com.example.aaaaa.MyButton
android:id="@+id/id_btn"
android:layout_width="150dp"
android:layout_height="150dp"
android:src="@drawable/ic_launcher"
android:text="click me" />
</com.example.aaaaa.MyLinear>
</LinearLayout>


public class MyLinear extends LinearLayout{
private static final String TAG =MyLinear.class.getSimpleName();

public MyLinear(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyLinear(Context context) {
super(context);
}

@Override
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();

switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "LinearLayout+onTouchEvent ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "LinearLayout+onTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "LinearLayout+onTouchEvent ACTION_UP");
break;
default:
break;
}
return super.onTouchEvent(event);
}

@Override
public boolean dispatchTouchEvent(MotionEvent event)
{
int action = event.getAction();

switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "LinearLayout+dispatchTouchEvent ACTION_DOWN");
//			return true;
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "LinearLayout+dispatchTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "LinearLayout+dispatchTouchEvent ACTION_UP");
break;

default:
break;
}
boolean a=super.dispatchTouchEvent(event);
//		Log.e(TAG, "LinearLayout:a="+a);
return a;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}
}


public class MyButton extends Button
{
private static final String TAG = MyButton.class.getSimpleName();
public MyButton(Context context, AttributeSet attrs)
{
super(context, attrs);
}

@Override
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();

switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "button+onTouchEvent ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "button+onTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "button+onTouchEvent ACTION_UP");
break;
default:
break;
}
return super.onTouchEvent(event);
}

@Override
public boolean dispatchTouchEvent(MotionEvent event)
{
int action = event.getAction();

switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "button+dispatchTouchEvent ACTION_DOWN");
//			return true;
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "button+dispatchTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "button+dispatchTouchEvent ACTION_UP");
break;

default:
break;
}
boolean a=super.dispatchTouchEvent(event);
//		Log.e(TAG, "button:a="+a);
return a;
//		return super.dispatchTouchEvent(event);
}
}


public class MyImage extends ImageView
{
private static final String TAG = MyImage.class.getSimpleName();

public MyImage(Context context, AttributeSet attrs)
{
super(context, attrs);
}

@Override
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();

switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "onTouchEvent ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "onTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "onTouchEvent ACTION_UP");
break;
default:
break;
}
return super.onTouchEvent(event);
}

@Override
public boolean dispatchTouchEvent(MotionEvent event)
{
int action = event.getAction();

switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "dispatchTouchEvent ACTION_DOWN");
return false;
//			break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "dispatchTouchEvent ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "dispatchTouchEvent ACTION_UP");
break;

default:
break;
}
boolean a=super.dispatchTouchEvent(event);
//		Log.e(TAG, "ImageView:a="+a);
return a;
//		return super.dispatchTouchEvent(event);
}
}
public class MainActivity extends Activity
{
protected static final String TAG = "MainActivity";
private MyImage imageView;
private MyButton button;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView=(MyImage) findViewById(R.id.id_ll);
button=(MyButton) findViewById(R.id.id_btn);
imageView.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Log.e(TAG, "setOnClickListener000");
}
});
button.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
Log.e(TAG, "button+setOnClickListener000");
}
});

final LinearLayout ll = (LinearLayout) findViewById(R.id.linear);
//		ll.setOnClickListener(new OnClickListener() {
//			@Override
//			public void onClick(View v) {
//				Log.e(TAG, "LinearLayout+setOnClickListener000");
//			}
//		});
//
ll.setOnTouchListener(new OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();

switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "LinearLayout+onTouch ACTION_DOWN");
Log.e(TAG, "LinearLayout+000"+ll.isClickable());
//					return false;
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "LinearLayout+onTouch ACTION_MOVE");
Log.e(TAG, "LinearLayout+000"+ll.isClickable());
//					return false;
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "LinearLayout+onTouch ACTION_UP");
Log.e(TAG, "LinearLayout+000"+ll.isClickable());
break;
default:
break;
}

return true;
}
});

imageView.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
int action = event.getAction();

switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "onTouch ACTION_DOWN");
Log.e(TAG, "000"+imageView.isClickable());
//					return false;
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "onTouch ACTION_MOVE");
Log.e(TAG, "000"+imageView.isClickable());
//					return false;
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "onTouch ACTION_UP");
Log.e(TAG, "000"+imageView.isClickable());
break;
default:
break;
}

return true;
}
});

button.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
int action = event.getAction();

switch (action)
{
case MotionEvent.ACTION_DOWN:
Log.e(TAG, "button+onTouch ACTION_DOWN");
//					Log.e(TAG, "button+000"+button.isClickable());
//					return false;
break;
case MotionEvent.ACTION_MOVE:
Log.e(TAG, "button+onTouch ACTION_MOVE");
//					Log.e(TAG, "button+000"+button.isClickable());
//					return false;
break;
case MotionEvent.ACTION_UP:
Log.e(TAG, "button+onTouch ACTION_UP");
//					Log.e(TAG, "button+000"+button.isClickable());
break;
default:
break;
}

return false;
}
});
}
}
代码都非常简单,基本都是打印信息,OK,那我们开始测试吧
如果轻轻点击自定义Button,并手抖一下,会打印出什么信息呢?让我们来look一look



如果轻轻点击自定义ImageView,并手抖一下,又会打印出什么信息呢?让我们来look一look



为什么会这样呢?
因为我在自定义ImageView的dispatchTouchEvent方法里的MotionEvent.ACTION_DOWN事件判断里返回了false,还记得我们上一篇结尾说的么?

***切记,只有每个ACTION_DOWN,ACTION_MOVE,ACTION_UP事件对应的dispatchTouchEvent方法都返回true,才能依次往后执行,就是说如果dispatchTouchEvent方法里此时的event.getAction()==ACTION_DOWN,
你返回了false,那么后面的dispatchTouchEvent方法都不会执行(说白了,每个动作事件都会执行一次dispatchTouchEvent,执行ACTION_DOWN的时候返回了false,后面一系列其它的action就不会再得到执行了,也就是[b]ACTION_MOVE,ACTION_UP事件将不会得到执行。
[/b]

到了这里我建议先结合两位大神的源码看看吧
/article/1562149.html

/article/1336233.html

看完以后再看看这张图,是不是瞬间明白了



实在想不明白的朋友可以把我上面的代码拷过去,根据自己的想法改一改,然后运行运行,很快你就会豁然开朗

总结:当点击布局里的控件时,首先会调用ViewGroup的dispatchTouchEvent方法,如果onInterceptTouchEvent方法返回的是false,那么就会调用子View的dispatchTouchEvent方法(这个方法返回true就表示子View把事件消费掉了),如果onInterceptTouchEvent方法返回的是true,那么就会调用ViewGroup的父类(也就是View)的dispatchTouchEvent方法,接下来调用布局的onTouch、onTouchEvent方法。

可以这么记着:布局把事情交给子View处理,子View的dispatchTouchEvent方法返回true表示它把事情干完了,布局就不处理了;如果返回false,就是子View没处理完,那么布局就要处理了。(再回过头去看 ***切记那里,明白了么?朋友,如果一个事件你返回了false,后面的就是布局在处理了,所以子View后面的事件不会执行)

好吧,我承认这篇写的有点水,其实主要是提供代码给大家运行着试试,自己动手,丰衣足食。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: