对安卓事件分发有了一个系统了解后,那我们现在说说我们项目中如何处理事件冲突
//以ScrollView嵌套scrollView两个ViewGruop上下滑动冲突问题为案列 xml代码如下
当我们滑动里面的scrollView时发现没有反应,说明触摸事件被父布局拦截了,
-------------------------------------------------------------方案一--------------------------------------------------------------------
自定义父ViewGroup,对拦截方法onInterClepTouchEvent()方法重新,返回false不拦截
代码如下
/**
* 父viewGroup处理拦截事件
*/
public class ScrollView1 extends ScrollView {
//手指滑动Y的距离
private int downY;
//获取触摸斜坡(作为滑动操作的参考值)
private int mTouchSlop;
public ScrollView1(Context context) {
super(context);
init(context);
}
public ScrollView1(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ScrollView1(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public ScrollView1(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
/**
* 外部处理拦截
*
* @param ev
* @return
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//获取滑动距离
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = (int) ev.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int moveY = (int) ev.getRawY();
if (Math.abs(moveY - downY) > mTouchSlop) {
return false;
}
break;
}
return super.onInterceptTouchEvent(ev);
}
}
、、修改后的xml代码
运行代码发现滑动里面的scollView的view可以滑动了,但是滑动ListView不能滑动。也就是说父布局不拦截子布局触摸事件后,如果子布局没有对触摸事件做对应处理就有问题了。
-------------------------------------------------------------方案二--------------------------------------------------------------------
一个自定义自己的ViewGroup,对拦截方法onInterClepTouchEvent()方法重新,请求父布局不拦截事件
Java代码
/**
* viewGroup处理拦截事件
*/
public class ScrollView2 extends ScrollView {
//手指滑动Y的距离
private int downY;
//获取触摸斜坡(作为滑动操作的参考值)
private int mTouchSlop;
public ScrollView2(Context context) {
super(context);
init(context);
}
public ScrollView2(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ScrollView2(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public ScrollView2(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
/**
* 外部处理拦截
*
* @param ev
* @return
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
//获取滑动距离
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
downY = (int) ev.getRawY();
//请求父布局不要拦截
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:
int moveY = (int) ev.getRawY();
if (Math.abs(moveY - downY) > mTouchSlop) {
//请求父布局不要拦截
getParent().requestDisallowInterceptTouchEvent(true);
}
break;
}
return super.onInterceptTouchEvent(ev);
}
}
修改后的xml代码
运行里面scrollView的触摸事件有了,滑动ListView也有了,完美解决
总结:对滑动冲突事件如果是上下滑动冲突就对Y方向触摸处理,如果左右就对X方向做处理,建议在当前有冲突的ViewGroup处理冲突事件。
源码 https://github.com/zhudaihao/ViewTounchEvent