view、viewGroup事件传递简单测试

来源:互联网 发布:手机4g网络测速在线 编辑:程序博客网 时间:2024/06/05 14:00

重写的view:

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;


public class EventButton extends Button {


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


public EventButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


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


@Override
public boolean onTouchEvent(MotionEvent event) {
System.out.println("Button onTouchEvent:" + event.getAction());
// switch (event.getAction()) {
// case MotionEvent.ACTION_DOWN:
// return false;
// default:
// break;
// }
return super.onTouchEvent(event);
}


@Override
public boolean dispatchTouchEvent(MotionEvent event) {
System.out.println("Buttonon dispatchTouchEvent:" + event.getAction());
// switch (event.getAction()) {
// case MotionEvent.ACTION_MOVE:
// return false;
// default:
// break;
// }
return super.dispatchTouchEvent(event);
}

}


重写的viewGroup:


package com.example.testviewevent;


import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.MeasureSpec;


public class EventViewGroup extends ViewGroup {


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


public EventViewGroup(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


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


@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childLeft = 0;
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != View.GONE) {
final int childWidth = child.getMeasuredWidth();
child.layout(childLeft, 0, childLeft + childWidth,
child.getMeasuredHeight());
childLeft += childWidth;
}
}
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
System.out.println("viewGroup dispatchTouchEvent:" + ev.getAction());
return super.dispatchTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
System.out.println("viewGroup onTouchEvent:" + event.getAction());
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
System.out.println("viewGroup onInterceptTouchEvent:" + ev.getAction());
return true;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// 测量页面及子控件宽度和高度
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException(
"Workspace can only be used in EXACTLY mode.");
}


final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException(
"Workspace can only be used in EXACTLY mode.");
}


final int count = getChildCount();
for (int i = 0; i < count; i++) {
getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
}
}

}

测试Activity:


import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActionBar.LayoutParams;
import android.graphics.Color;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;


public class MainActivity extends Activity {
private EventButton btn;
private EventViewGroup viewGroup;
    @SuppressLint("NewApi") @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (EventButton) findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
System.out.println("Button was Clicked!");
}
});
        viewGroup = (EventViewGroup) findViewById(R.id.viewGroup);
        viewGroup.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
System.out.println("ViewGroup was Clicked!");
}
});
        EventButton child = new EventButton(this);
        child.setText("I am a child");
        child.setBackgroundColor(Color.WHITE);
        LayoutParams param = new LayoutParams(50, 50);
        param.setMargins(10, 10, 10, 10);
        child.setLayoutParams(param);
        viewGroup.addView(child);
    }
}

总结:
1、View事件传递
     1)dispatchTouchEvent,分发事件,onTouchEvent返回true,它就返回true。如果action_down事件返回false,那么后续的事                     件如action_move、action_up等将不会得到处理。
        2)onTouchEvent,如果action_down事件返回false,那么后续的事件如action_move、action_up等将不会得到处理。
2、ViewGroup事件传递
      1)dispatchTouchEvent:与View类似。
         2)onInterceptTouchEvent:默认返回false,表示不拦截。子类需要重写这个方法。
         3)onTouchEvent:与View类似。
3、ViewGroup里面包含子View的事件传递
     设viewGroup里面包含了一个子view,名为child。首先是viewGroup先收到事件。dispatchTouchEvent首先处理,接着是onInterceptTouchEvent,若onInterceptTouchEvent返回true,那么此事件由viewGroup处理,接着会执行viewGroup的onTouchEvent,也就是被拦截了;若onInterceptTouchEvent返回false,那么此事件将会交由viewGroup的子view进行处理,view的dispatchTouchEvent方法首先执行,然后是view的onTouchEvent方法被执行。
         此时,重点来了。
         若onTouchEvent方法返回false,那么down事件就到了viewGroup,若viewGroup的ontouchEvent返回true,那么后续事件都将由viewGroup处理;若返回false,那么后续事件将不会得到处理。
         若onTouchEvent方法返回true,那么接下来的move、up等事件都交由view处理。
         此时viewGroup将会对move事件进行拦截,若onInterceptTouchEvent返回false,那么view将完全代理所有事件;若返回true,那么将强制发送cancel事件给view,move事件和up事件将由viewGroup进行处理。

手绘图一张:


0 0