package com.example.testview;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.Button;
public class CustomButton extends Button {
/*
* public CustomButton(Context context,AttributeSet attrs, int defStyle) {
* super(context, attrs, defStyle); // TODO Auto-generated constructor stub
* }
*/
public CustomButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
int mlastx;
int mlasty;
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e("TestView","down事件");
break;
case MotionEvent.ACTION_MOVE:
Log.e("TestView","Move事件");
int inx = x - mlastx;
int iny = y - mlasty;
// 应该用的是nineoldandroids的viewhelper
int tranx = (int) (this.getTranslationX() + inx);
int trany = (int) (this.getTranslationY() + iny);
this.setTranslationX(tranx);
this.setTranslationY(trany);
break;
case MotionEvent.ACTION_UP:
break;
default:
break;
}
mlastx = x;
mlasty = y;
// getParent().requestDisallowInterceptTouchEvent(false);
return true;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
// TODO Auto-generated method stub
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
return super.dispatchTouchEvent(event);
}
}
package com.example.testview;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.FrameLayout;
public class CustomViewGroup extends FrameLayout{
public CustomViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
/**
* 外部拦截法和内部拦截法, 父和子
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
return super.dispatchTouchEvent(ev);
}
//只有viewgroup特有的事件,就只执行一次,down事件执行
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
return false;
case MotionEvent.ACTION_MOVE: //表示父类需要
if(业务条件) {
return true;
}
else {
return false;
}
case MotionEvent.ACTION_UP:
return false;
default:
break;
}
// TODO Auto-generated method stub
Log.e("TestView","父容器拦截");
return false; //如果设置拦截,除了down,其他都是父类处理
}
@Override
public boolean onTouchEvent(MotionEvent event) { //父容器处理
// TODO Auto-generated method stub
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.e("TestView","父容器down");
break;
case MotionEvent.ACTION_MOVE:
Log.e("TestView","父容器move");
break;
default:
break;
}
/* Log.e("TestView","父容器处理");*/
return false;
}
}
首先我们自定义2个类,一个是子View,另一个是父View, 子可能是个listview,父可能是一个scrollview.
滑动冲突分多种,有可能是同方向的滑动,也可能是水平和竖直方向的。那为什么会滑动冲突呢,关键是2个类都接到了同样的事件,解决的思路就是同一时刻只能有一个VIew处理MotionEvent事件,解决方法由2种
外部拦截法和内部拦截法
1.外部,故名思议是在父View的onInterceptTouchEvent处理.
它针对3中不同的事件做处理,
对于down, 返回false,除非你希望那个让父View完全处理这3个事件。由于这里是false.所以同一事件序列的其他2个事件父view肯定能执行到(除非设置一个tag),
对于move,看业务情况,返回true代表父类来消耗,false则表示子类,
对于up,返回false.除非你想让子View的click这种都无法用。
2.内部,重写子元素的dispatchTouchEvent方法。默认情况下父View可以写成除了down,其他都拦截,然后在子View里用parent,requestDisallowInterceptTouchEvent()