Android中滑动冲突的解决方案

3 篇文章 0 订阅
1 篇文章 0 订阅
    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;
    }
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值