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

Android中滑动冲突的解决方案

2016-04-08 12:59 411 查看
1外部拦截法
需要在父容器中重写onInterceptTouchEvent()
//处理滑动冲突: 外部拦截法
//所有点击事件均经过父容器处理,如果父容器需要就拦截,否则就不拦截

boolean needEvent;//是否需要处理此事件

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercepted = false;
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
intercepted = false;
break;
case MotionEvent.ACTION_MOVE:
if (needEvent) {
intercepted = true;
} else {
intercepted = false;
}
break;
case MotionEvent.ACTION_UP:
intercepted = false;
break;
}
return intercepted;
}

二 内部拦截法
//重写在父类中的方法
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {

if (ev.getAction() == MotionEvent.ACTION_DOWN) {
return false;
} else {
return true;
}
}

//重写子类中的方法
boolean needEvent;//是否需要处理此事件

//内部拦截法: 父类默认拦截除了DOWN以外的所有事件
//在子类中默认让父类不拦截任何事件,然后子类拦截自己需要的事件
//再将不需要的事件让父类拦截
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
//让父类不拦截任何事件
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
if (needEvent) {
getParent().requestDisallowInterceptTouchEvent(true);
} else {
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
break;
}

return super.dispatchTouchEvent(ev);
}

实例
两个ScrollView的时候,一个可以垂直滑动,一个可以水平滑动,垂直滑动的嵌套水平滑动的,
此时在可以水平滑动的ScrollView中做竖直滑动,会发现外面的可以竖直滑动的ScrollView不会滑动,此时
出现了滑动冲突,可以自定义ScrollView来解决这个冲突

无滑动冲突的ScrollView,采用外部拦截法

/**
* Created by Venn on 2016/4/8.
* 竖直滑动的ScrollView并且里面可以嵌套水平滑动的ScrollView
* 且不会引起滑动冲突
*/
public class OutScrollView extends LinearLayout {

private Context mContext;
private Scroller mScroller;
private int lastX;
private int lastY;
private int judgeX;
private int judgeY;

public OutScrollView(Context context) {
this(context, null);
}

public OutScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init();
}

private void init() {
mScroller = new Scroller(mContext);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);//使用父类的布局方法
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercepted = false;
int x = (int) ev.getRawX();
int y = (int) ev.getRawY();
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
intercepted = false;
judgeX = x;
judgeY = y;
if (!mScroller.isFinished()) {//如果一次滑动没处理完,再次按下,则放弃上次滑动,并且将后续事件交给自己处理
mScroller.abortAnimation();
intercepted = true;
}
break;
case MotionEvent.ACTION_MOVE:

int dX = x - judgeX;
int dY = y - judgeY;
if (Math.abs(dX) > Math.abs(dY)) {//如果水平滑动的距离大于竖直滑动的距离,就认为是水平滑动,否则就是竖直滑动
intercepted = false;
} else {
intercepted = true;
}

break;
case MotionEvent.ACTION_UP:
intercepted = false;
break;
}

judgeX = x;
judgeY = y;
lastX = x;
lastY = y;
return intercepted;
}

@Override
public boolean onTouchEvent(MotionEvent event) {

int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = x;
lastY = y;
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
break;
case MotionEvent.ACTION_MOVE:
int dX = x - lastX;
int dY = y - lastY;
scrollBy(0, -dY);//因为只处理竖直滑动,所以水平方向默认为0
break;
case MotionEvent.ACTION_UP:
break;
}

lastX = x;
lastY = y;

return true;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: