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);
}
}
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);
}
}
}
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
- view、viewGroup事件传递简单测试
- Android ViewGroup和View的传递事件
- ViewGroup和View的事件传递原理
- ViewGroup与子View之间事件传递
- View及ViewGroup的事件分发及传递(一)
- View及ViewGroup的事件分发及传递(二)
- View及ViewGroup的事件分发及传递(一)
- View及ViewGroup的事件分发及传递(二)
- View及ViewGroup的事件分发及传递(一)
- View及ViewGroup的事件分发及传递(二)
- [Android 分享] View 和 ViewGroup 事件传递机制
- View及ViewGroup的事件分发及传递(一)
- View及ViewGroup的事件分发及传递(二)
- Android 之在View以及ViewGroup中Touch事件传递
- ViewGroup事件传递机制
- ViewGroup事件传递机制
- ViewGroup View触摸事件
- android view触摸事件传递机制测试
- 单链表常见操作
- Android Studio And Gradle
- 使用Managed DirectX创建三维地形
- 给初学者的 Android 加密工具
- android混淆代码
- view、viewGroup事件传递简单测试
- Java的多线程编程模型2--怎样才线程安全
- 第五章:纹理
- JAVA,AES加密算法
- 给初学者,OC知识的简单总结
- oracle 11g不能导出空表的多种解决方法
- eclipse中导入jar包的源码
- JAVA下wordpress加密
- ap0100at_ds移植步骤