Viewpager和SeekBar的滑动冲突的解决办法(其他滑动冲突可参考)

来源:互联网 发布:法律讲堂网络 编辑:程序博客网 时间:2024/06/04 18:11

Android开发中滑动冲突非常常见,下面介绍一下我在项目开发中遇到的问题及解决方法。

一、问题描述:在ViewPager+Fragment的配合使用中,在fragment的布局中使用到了SeekBar,此时会出现SeekBar只在第一次滑动的时候好用,之后的滑动都只能ViewPager有效,SeekBar滑动失效。
二、解决办法:重新自定义ViewPager和SeekBar,代码如下:

自定义的ViewPager

import android.content.Context;import android.support.v4.view.ViewPager;import android.util.AttributeSet;import android.view.MotionEvent;/** * Created by leven on 2017/4/20. */public class NoScrollViewPager extends ViewPager {    private boolean noScroll = false;    public NoScrollViewPager(Context context, AttributeSet attrs) {        super(context, attrs);    }    public NoScrollViewPager(Context context) {        super(context);    }    //控制是否可滑动    public void setNoScroll(boolean noScroll) {        this.noScroll = noScroll;    }    @Override    public void scrollTo(int x, int y) {        super.scrollTo(x, y);    }    @Override    public boolean onTouchEvent(MotionEvent arg0) {        if (noScroll)            return false;        else            return super.onTouchEvent(arg0);    }    //请求允许打断滑动或不允许打断该组件的滑动事件    @Override    public boolean onInterceptTouchEvent(MotionEvent arg0) {        if (noScroll){            getParent().requestDisallowInterceptTouchEvent(false);            return false;        } else{            return super.onInterceptTouchEvent(arg0);        }    }    @Override    public void setCurrentItem(int item, boolean smoothScroll) {        super.setCurrentItem(item, smoothScroll);    }    @Override    public void setCurrentItem(int item) {        super.setCurrentItem(item);    }}

自定义的SeekBar

import android.content.Context;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.SeekBar;import com.dfwy.cxy.xiahubao.message.MessageEvent;import org.greenrobot.eventbus.EventBus;/** * Created by leven on 2017/5/4. */public class ScrollableSeekBar extends SeekBar {    boolean touchingProgressBar = true;    public ScrollableSeekBar(Context context) {        super(context);    }    public ScrollableSeekBar(Context context, AttributeSet attrs) {        super(context, attrs);    }    public ScrollableSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    public void setTouchingProgressBar(boolean touchingProgressBar) {        this.touchingProgressBar = touchingProgressBar;    }    @Override    public boolean onTouchEvent(MotionEvent event) {        if(touchingProgressBar){            super.onTouchEvent(event);            switch (event.getAction()) {                case MotionEvent.ACTION_DOWN:                    System.out.println("MotionEvent.ACTION_DOWN");                    //请求触摸事件不被打断                    getParent().requestDisallowInterceptTouchEvent(true);                    touchingProgressBar = true;                    break;                case MotionEvent.ACTION_UP:                    System.out.println("MotionEvent.ACTION_UP");                    //当结束滑动时请求触摸事件可以被打断                    getParent().requestDisallowInterceptTouchEvent(false);                    touchingProgressBar = true;                    break;                case MotionEvent.ACTION_CANCEL:                    getParent().requestDisallowInterceptTouchEvent(false);                    break;            }        } else {        }        return true;    }    //此处非常重要, 返回true,后续事件(ACTION_MOVE、ACTION_UP)会再传递    @Override    public boolean dispatchTouchEvent(MotionEvent event) {        System.out.println("dispatchTouchEvent");        super.dispatchTouchEvent(event);        return true;    }}

SeekBar在代码中的操作

    mSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){        @Override        public void onProgressChanged(SeekBar seekBar,int i,boolean b){        }        @Override        public void onStartTrackingTouch(SeekBar seekBar){            //发送通知让ViewPager不可滑动        getParentFragment()).getViewPagerTask().setNoScroll(true);            EventBus.getDefault().post(new MessageEvent("NoScrollableViewPager"));            if(seekBar.getParent()!=null){                seekBar.getParent().requestDisallowInterceptTouchEvent(true);            }        }        @Override        public void onStopTrackingTouch(SeekBar seekBar){            //发送通知让ViewPager可滑动            EventBus.getDefault().post(new MessageEvent("ScrollableViewPager"));            getParentFragment()).getViewPagerTask().setNoScroll(false);            surveyChoiceListBean.setVALUE(String.valueOf(seekBar.getProgress()-100));        }

总结:这里主要是滑动事件的滑动顺序及处理,事实上,滑动事件的分发机制还是稍微有点复杂的,首先执行的是父组件的dispatchTouchEvent方法,返回true时继续向下传递,此时可以控制父组件的滑动方法让其不可滑动,然后事件传递到子组件的dispatchTouchEvent方法,该方法返回true继续传递到该组件的滑动方法,然后可以在滑动方法中做一些操作,在滑动执行完成时可以让父组件的滑动恢复正常,这就是我在解决滑动冲突的思路,希望可以给大家带来帮助。。

阅读全文
1 0
原创粉丝点击