Android开发模板------ViewPager(三):实现无限循环、可嵌套RecyclerView、可控制滑动速度

一、使用

布局就不贴了,直接写业务逻辑:

private ViewPager mPager;
    private LinearLayout mVPIndicate;
    private void initPager() {
        mPager = (ViewPager)findViewById(R.id.mPager);
        mVPIndicate = (LinearLayout)findViewById(R.id.mVPIndicate);
        List<View> mViews = mVPController.createGridRecyclerS(
                mVPController.initViewPagerData(Arrays.asList(hotWordDefList)));
        final int pageCount = mViews.size();
        mPager.setAdapter(new LoopVPAdapter(mViews));
        mVPController.setVPSlideEnable(mPager);

        final List<ImageView> mVPIndicateImgView = mVPController.initViewPagerIndicate(pageCount - 1);
        for (ImageView childImg : mVPIndicateImgView) {
            mVPIndicate.addView(childImg);
        }

        mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                Drawable noSelected = Main2Activity.this.getResources().getDrawable(R.drawable.ad_white_dot);
                Drawable selected = Main2Activity.this.getResources().getDrawable(R.drawable.ad_selected_dot);
                for (int i = 0; i < pageCount; i++) {
                    if (i == pageCount - 1) {
                        if (position == i) {
                            mVPIndicateImgView.get(0).setImageDrawable(selected);
                        }
                    } else if (position != i) {
                        mVPIndicateImgView.get(i).setImageDrawable(noSelected);
                    } else {
                        mVPIndicateImgView.get(i).setImageDrawable(selected);
                    }
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                int currentPosition = mPager.getCurrentItem();
                if (state != ViewPager.SCROLL_STATE_IDLE)
                    return;
                if (currentPosition >= pageCount - 1) {
                    mPager.setCurrentItem(0, false);
                } else {
                    mPager.setCurrentItem(currentPosition, false);
                }
            }
        });
    }

二、辅助控制类VPController

public class VPController {
    private Context context;
    private Subscription subscription;
    private final static int NumPerVP = 8;
    public VPController(Context context) {
        this.context = context;
    }

    public List<String[]> initViewPagerData(List<String> mListData) {
        List<String[]> resultList = new ArrayList<>();

        int hotWordSize = mListData.size();
        int pageSize = (hotWordSize / NumPerVP) + ((hotWordSize % NumPerVP) > 0 ? 1 : 0);
        for (int i = 0; i < pageSize; i++){
            String[] hotWord = new String[NumPerVP];
            for (int j = i * NumPerVP; j < (i + 1) * NumPerVP && j < hotWordSize; j++){
                hotWord[j % NumPerVP] = mListData.get(j);
            }
            resultList.add(hotWord);
        }
        return resultList;
    }

    private RecyclerView createGridRecycler(final List<String> mData) {
        RecyclerView mRecycler = new RecyclerView(context);
        mRecycler.setLayoutManager(new GridLayoutManager(context, 2));
        HotSearchAdapter gridAdapter = new HotSearchAdapter();
        mRecycler.setAdapter(gridAdapter);
        gridAdapter.setLists(mData);
        gridAdapter.setOnItemClickListener(new OnRecyclerItemClickListener() {
            @Override
            public void onItemRecyclerClick(Object object) {
                Log.i("TAG", "onItemRecyclerClick");
            }
        });
        return mRecycler;
    }

    public List<View> createGridRecyclerS(List<String[]> source) {
        source.add(source.get(0));
        List<View> resultList = new ArrayList<>();
        for (String[] datas : source) {
            resultList.add(createGridRecycler(Arrays.asList(datas)));
        }
        return resultList;
    }

    /**
     * 生成指示器
     * @param size
     * @return
     */
    public List<ImageView> initViewPagerIndicate(int size) {
        List<ImageView> result = new ArrayList<>();
        ImageView mImg ;
        for (int i = 0; i < size; i++){
            mImg = new ImageView(context);
            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(10,10);
            layoutParams.setMargins(10, 0, 0, 0);
            mImg.setLayoutParams(layoutParams);
            result.add(mImg);
            if (i == 0) {
                mImg.setImageDrawable(context.getResources().getDrawable(R.drawable.ad_selected_dot));
            } else {
                mImg.setImageDrawable(context.getResources().getDrawable(R.drawable.ad_white_dot));
            }
        }
        return result;
    }

    /**
     * 左右滑动的动画降速
     * @param mViewPage
     */
    public void vpSlideVelocityControl(ViewPager mViewPage) {
        try {
            Field mScroller = ViewPager.class.getDeclaredField("mScroller");
            mScroller.setAccessible(true);
            Interpolator sInterpolator = new AccelerateDecelerateInterpolator();
            FixedScroller scroller = new FixedScroller(mViewPage.getContext(), sInterpolator);
            mScroller.set(mViewPage, scroller);
        } catch (Exception e) {
            Log.e("exception", e.getMessage());
        }
    }

    /**
     * 是否启动向右无限循环滑动
     * @param mViewPage
     */
    public void setVPSlideEnable(final ViewPager mViewPage) {
        subscription = Observable.interval(3000, 3000, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        int currentIndex = mViewPage.getCurrentItem();
                        mViewPage.setCurrentItem(currentIndex + 1, true);
                    }
                });
    }

    /**
     * 和setVPSlideEnable()相对于,关闭自动滑动
     */
    public void setVPSlideDisenable() {
        if (subscription != null) {
            subscription.unsubscribe();
        }
    }
}

以上就是完整的使用,就是这么简单粗暴,不做任何扩展!
实现图片的更加简单。可以直接修改。

三、原理

下面简单说下原理吧,主要是在ViewPager.OnPageChangeListener修改:

@Override
public void onPageScrollStateChanged(int state) {
    int currentPosition = mPager.getCurrentItem();
    if (state != ViewPager.SCROLL_STATE_IDLE)
        return;
    if (currentPosition >= pageCount - 1) {
        mPager.setCurrentItem(0, false);
    } else {
        mPager.setCurrentItem(currentPosition, false);
    }
}

————————————>无限的向右循环

View1 View2 View3 View11
其实想表达的是如果你有三个页面需要展示,那么就在List里面多添加一个View,添加第一个View到List表尾就行了。之所以这样做,其实就是为了掩盖最后一项滑动第一项那个不太友好的动画。处理的逻辑是,当正在现实最后一项的时候,手动设置mPager.setCurrentItem(0, false);成第一项,这个是没有动画的,至少人的肉眼是看不到有什么变化的,这样就又从第一项开始循环下去。
注意指示器处的设置别出错,因为我们虽然有四个页面,但实际上我们要显示的是三页:

@Override
public void onPageSelected(int position) {
    Drawable noSelected = Main2Activity.this.getResources().getDrawable(R.drawable.ad_white_dot);
    Drawable selected = Main2Activity.this.getResources().getDrawable(R.drawable.ad_selected_dot);
    for (int i = 0; i < pageCount; i++) {
        if (i == pageCount - 1) {
            if (position == i) {
                mVPIndicateImgView.get(0).setImageDrawable(selected);
            }
        } else if (position != i) {
            mVPIndicateImgView.get(i).setImageDrawable(noSelected);
        } else {
            mVPIndicateImgView.get(i).setImageDrawable(selected);
        }
    }
}

顺便把参考网上的FixedScroller也贴上来吧:

public class FixedScroller extends Scroller {
    private int mDuration = 500;


    public FixedScroller(Context context) {
        super(context);
    }


    public FixedScroller(Context context, Interpolator interpolator) {
        super(context, interpolator);
    }


    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }


    @Override
    public void startScroll(int startX, int startY, int dx, int dy) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }
}

四、无限循环的另一种实现方式

实现原理:在适配器中将getcount的值设置为无限大
然后就是在adapter中的实现:

public class ViewPagerAdapter extends PagerAdapter {

        @Override
        public int getCount() {
//            return drawables.length;
            return Integer.MAX_VALUE;
        }

        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            ImageView view = imageViews[position % imageViews.length];
            ((ViewPager) container).removeView(view);
        }

        @Override
        public Object instantiateItem(View container, int position) {
            int length = imageViews.length;
            try {
                if (imageViews[position % length].getParent() == null) {
                    ((ViewPager) container).addView(imageViews[position % length], 0);
                } else {
                    ((ViewGroup) (imageViews[position % length].getParent()))
                            .removeView(imageViews[position % length]);
                }
            } catch (Exception e) {
            }
            return imageViews[position % imageViews.length];
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值