李氏滑動事件衝突解決方案 之 處理子ViewGroup的超棒方案

  父ViewGroup(CurView) 和 子 ViewGroup(ParentView) 滑動事件衝突解決方案 之 處理子ViewGroup的超棒方案:android

子ViewGroup 以 SlipRelativeLayout 爲例子:ide

  • 當 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;
    }

}
相關文章
相關標籤/搜索