父ViewGroup(CurView) 和 子 ViewGroup(ParentView) 滑动事件冲突解决方案 之 处理子ViewGroup的超棒方案:
子ViewGroup 以 SlipRelativeLayout 为例子:
- 当 mEnableX=true, mEnableY=false 时, SlipRelativeLayout 中所有的 横向滑动事件都交给自己处理,横向滑动事件都交给 ParentView 处理;
- 当 mEnableX=false, mEnableY=true 时, SlipRelativeLayout 中所有的 纵向滑动事件都交给自己处理,纵向滑动事件都交给 ParentView 处理;
- 当 mEnableX=true, mEnableY=true 时, SlipRelativeLayout 中所有的 横向和纵向滑动事件都交给自己处理,ParentView 不处理任何事件;
- 当 mEnableX=false, mEnableY=false 时, SlipRelativeLayout 中所有的 自己不处理任何滑动事件,所有事件都交给 ParentView 处理;
import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.ViewParent; import android.widget.RelativeLayout; public class SlipRelativeLayout extends RelativeLayout { public static final String TAG = "SlipRelativeLayout"; private boolean mEnable = false, mEnableX = true, mEnableY = false; private float xDistance, yDistance; private float xStart, yStart; private float xEnd, yEnd; public SlipRelativeLayout(@NonNull Context context) { super(context); } public SlipRelativeLayout(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); } public SlipRelativeLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public boolean ismEnable() { return mEnable; } public void setmEnable(boolean mEnable) { this.mEnable = mEnable; } public boolean ismEnableX() { return mEnableX; } public void setmEnableX(boolean mEnableX) { this.mEnableX = mEnableX; } public boolean ismEnableY() { return mEnableY; } public void setmEnableY(boolean mEnableY) { this.mEnableY = mEnableY; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return super.onInterceptTouchEvent(ev); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (null == ev) return false;//不截事件 switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: xDistance = yDistance = 0f; xStart = ev.getX(); yStart = ev.getY(); getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_MOVE: xEnd = ev.getX(); yEnd = ev.getY(); xDistance = xEnd - xStart; yDistance = yEnd - yStart; getParent().requestDisallowInterceptTouchEvent(needIntercept()); break; default: break; } return super.dispatchTouchEvent(ev); } private boolean needIntercept() { ViewParent viewparent = getParent(); if (null != viewparent) { boolean disallowIntercept; float distance = Math.abs(xDistance) - Math.abs(yDistance); if ((mEnableX && distance > 0) || (mEnableY && distance < 0) || mEnable) {//拦截X事件向下分发 disallowIntercept = true; } else { disallowIntercept = false; } return disallowIntercept; } return false; } }