在viewpager中嵌套fragment再嵌套viewpager的事件分发问题解决

在现在的应用中经常能碰到在activity中,一个viewpager+tab然后pager内嵌套fragment再内嵌viewpager+fragment,在组合多样化的同时也带来了一些问题。

嵌套情况下pager的事件分发

在实际应用中我最开始使用的是v4包的viewpager,测试发现的问题是,当我操作内层pager的时候,只能滑动一点点距离然后触摸事件马上被外层pager抢走,内层根本无法滑动切换页面。

此问题的解决办法是,重写子pager,为子pager添加自己的点击事件。

嵌套情况下子pager滑到边缘的事件分发条件

只添加了点击事件修改了调用之后,内层pager可以滑动了,但是当内层pager滑到边缘的时候,我继续滑动,想要再把事件分发给外层pager来操作。

解决办法:在touch事件中记录点击的坐标,在move事件中通过x轴坐标计算判断滑动的方向和是否在最后一页时继续左划或者在第一页时继续右划。添加了配置总页数的方法

以下为重写的子viewpager的代码

public class ChildViewPager extends ViewPager{
    /** 触摸时按下坐标 **/
    PointF downP = new PointF();
    /** 触摸时当前坐标 **/
    PointF curP = new PointF();
    OnSingleTouchListener onSingleTouchListener;
    /** 当前pager的总页数 **/
    int listCount;
    public ChildViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public ChildViewPager(Context context) {
        super(context);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent arg0) {
        //在此位置返回true,将事件拦截在子pager中
        return true;
    }
    //添加总页数记录,在给pager配置adapter时要调用此方法把总页数添加进来
    public void setListSize(int size){
        listCount = size;
    }
    //获取总页数
    public int getFragmentCount(){
        return listCount;
    }
    @Override
    public boolean onTouchEvent(MotionEvent arg0) {
        //每次onTouch事件触发时都记录当前按下的坐标
        curP.x = arg0.getX();
        curP.y = arg0.getY();

        if(arg0.getAction() == MotionEvent.ACTION_DOWN){
            //记录按下时候的坐标
            downP.x = arg0.getX();
            downP.y = arg0.getY();
            //此句代码是避免父pager对操作进行干扰
            getParent().requestDisallowInterceptTouchEvent(true);
        }

        if(arg0.getAction() == MotionEvent.ACTION_MOVE){
            //判断是否是在第一个页面继续右划或者是否在最后一个页面时继续左划
            //如果是,把事件给到父级pager
            if(getCurrentItem()==getFragmentCount()-1&&downP.x-curP.x>0||getCurrentItem()==0&&downP.x-curP.x<0){
                getParent().requestDisallowInterceptTouchEvent(false);
            }else{
                getParent().requestDisallowInterceptTouchEvent(true);
            }
        }

        if(arg0.getAction() == MotionEvent.ACTION_UP){
            //在此时判断按下和松手是否在同一位置
            //如果是,执行自己写的点击事件
            if(downP.x==curP.x && downP.y==curP.y){
                onSingleTouch();
                return true;
            }
        }
        return super.onTouchEvent(arg0);
    }

    //点击事件
    public void onSingleTouch() {
        if (onSingleTouchListener!= null) {
            onSingleTouchListener.onSingleTouch();
        }
    }

    //创建点击事件接口
    public interface OnSingleTouchListener {
        public void onSingleTouch();
    }

    public void setOnSingleTouchListener(OnSingleTouchListener 
            onSingleTouchListener) {
        this.onSingleTouchListener = onSingleTouchListener;
    }
}

再配上自己重写的FragmentPagerAdapter

public class MyFragmentPagerAdapter extends FragmentPagerAdapter{
    private List fragments = new ArrayList();
    public void addFragment(Fragment fragment){
        if(fragment!=null){
            this.fragments.add(fragment);
        }
    }

    public MyFragmentPagerAdapter(FragmentManager fm) {
        super(fm);
    }


    @Override
    public Fragment getItem(int arg0) {
        return fragments.get(arg0);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }
}

你可能感兴趣的:(控件)