上一节我们讲过了安卓的事件分发的机制,因为事件分为容器viewgroup和view,而上一篇我们已经说过了view的事件分发机制,所以我们这篇就主要讲viewgroup的分发机制,其实viewgroup就是多了一个onInterceptTouchEvent。因为他会进行拦截,拦截了的话就不会传递给子view。下面用列子开讲:
首先还是写一个自定义viewgroup,我们让这个类继承linelayout,讲这个作为容器:
自定义viewgroup的类group:
public class group extends LinearLayout{
public group(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("haha", "groupdispatchdown");
break;
case MotionEvent.ACTION_MOVE:
Log.d("haha", "dispatchgroupmove");
break;
case MotionEvent.ACTION_UP:
Log.d("haha", "groupdispatchup");
break;
}
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("haha", "groupontouchevndown");
break;
case MotionEvent.ACTION_MOVE:
Log.d("haha", "groupontouchevnmove");
break;
case MotionEvent.ACTION_UP:
Log.d("haha", "groupontouchevnup");
break;
}
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("haha", "groupinterceptdown");
return true;
case MotionEvent.ACTION_MOVE:
Log.d("haha", "groupinterceptmove");
break;
case MotionEvent.ACTION_UP:
Log.d("haha", "groupinterceptup");
break;
}
return super.onInterceptTouchEvent(event);
}
}
一个自定义view,就和上节的一样,button:
public class button extends Button{
public button(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("haha", "dispatchdown");
break;
case MotionEvent.ACTION_MOVE:
Log.d("haha", "dispatchmove");
break;
case MotionEvent.ACTION_UP:
Log.d("haha", "dispatchup");
break;
}
//return false;
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("haha", "onchdown");
break;
case MotionEvent.ACTION_MOVE:
Log.d("haha", "onmove");
break;
case MotionEvent.ACTION_UP:
Log.d("haha", "onchup");
break;
}
return super.onTouchEvent(event);
}
}
然后就是activity以及xml文件:
public class viewgroup extends Activity implements OnTouchListener{
private group g;
private button b;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.haha);
g=(group)findViewById(R.id.g);
g.setOnTouchListener(this);
b=(button)findViewById(R.id.b);
b.setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if(v.getId()==R.id.b){
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("haha", "bdown");
break;
case MotionEvent.ACTION_MOVE:
Log.d("haha", "bmove");
break;
case MotionEvent.ACTION_UP:
Log.d("haha", "bup");
break;
}
}
if(v.getId()==R.id.g){
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("haha", "groupdown");
break;
case MotionEvent.ACTION_MOVE:
Log.d("haha", "groupmove");
break;
case MotionEvent.ACTION_UP:
Log.d("haha", "groupup");
break;
}
}
return false;
}
}
xml文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.viewgroup.group
android:id="@+id/g"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<com.example.dispatchevent.button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/b"
/>
</com.viewgroup.group>
</LinearLayout>
好这些就是我们自己设置的类:
然后进行事件分发,看下图:
从上面其实可以看出,其实viewgroup的事件分发和view的基本一致,唯一的区别就是viewgroup是个容器,他多了一个拦截机制,用于判断是否要传给子view,可能有些人会问,一个容器不可能只有一个view,如果是多个view,怎么办?其实差不多,因为每一个view的位置是固定的,所以你点击的位置就会触发哪一个位置view的事件。