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

关于android 的事件分发机制

2017-08-03 11:16 281 查看
android 关于事件分发的三个方法:

dispatchTouchEvent代表事件分发,返回值为true或false都表示不分发,返回super.dispatchTouchEvent表示将事件分发下去

onInterceptTouchEven代表事件拦截(ViewGroup特有的事件),返回值为true表示拦截事件,交给ViewGroup的OnTouchEvent处理,返回值为false表示交给子view的dispatchTouchEvent进行事件分发

onTouchEvent代表事件消费,返回值为true表示消费,返回值为false表示不消费,该事件将交给父控件的onTouchEvent进行处理

首先在dispatchTouchEvent中最先执行的就是onTouch方法,而onClick的调用是在onTouchEvent(event)方法中,因此onTouch肯定是要优先于onClick执行的。

而如果在onTouch方法里返回了true,就会让dispatchTouchEvent方法直接返回true,不会再继续往下执行。

下附代码说明,有兴趣的可以直接跑一下验证

public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
Button btn = (Button) findViewById(R.id.btn);
ll.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "LinearLayout: ");
}
});
ll.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "Button: ");
}
});
btn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
}
});
}
}


以上面这段代码为例子,如果我重写了LinearLayout中的onInterceptTouchEvent并返回true

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.e(TAG, "MyLayout onInterceptTouchEvent default return " + super.onInterceptTouchEvent(ev));
return super.onInterceptTouchEvent(ev);
}

改成

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
Log.e(TAG, "MyLayout onInterceptTouchEvent default return " + super.onInterceptTouchEvent(ev));
return true;
}

然后添加一句代码

btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "Button: ");
btn.setText( "Button: ");
}
});


运行之后,btn不会触发点击事件,因为事件被MyLayout拦截了,转而触发MyLayout的点击事件,如果这个时候设置onTouch事件返回true,那么连MyLayout的点击事件
4000
也不会触发,因为OnTouchEvent没有接受到事件,在OnTouchEvent内部被调用的OnClick事件自然也不会触发

最后再补充一句,ViewGroup和View都有dispatchTouchEvent方法,如果在ViewGroup里面dispatchTouchEvent的返回值为true,那么事件就不会分发下去,在我这个例子里面就是没有触发btn的点击事件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: