横向RecyclerView + PagerSnapHelper |(+ MagicIndicator)

5,210 阅读2分钟
项目中经常使用到 MagicIndicator + ViewPager 的布局,但是 有些情况 总感觉 (MagicIndicator + ViewPager)实现横向滑动有点大动干戈的感觉,RecyclerView + PagerSnapHelper 这种方式感觉更小巧,且可以轻松实现,但MagicIndicator并没有提供bind RecyclerView的方式。所以,如果能 RecyclerView + PagerSnapHelper + MagicIndicator 应该挺不错的。

简单实现一个 横向的 RecyclerView + PagerSnapHelper + MagicIndicator

  1. RecyclerView + PagerSnapHelper + MagicIndicator
    关键代码:
    rvReview.bind(magicIndicator);//绑定
    rvReview.setCurrentPosition(index); //切换页面

    1. 声明指示器
     commonNavigator = new CommonNavigator(this);
     commonNavigator.setSmoothScroll(false);
     commonNavigator.setAdjustMode(true);
     magicIndicator.setNavigator(commonNavigator);
    
    2. 绑定
    rvReview.bind(magicIndicator);
    
    3.左右切换 监听
    rvReview.setPageScollListener(new RvPagerView.PageScollListener() {
            @Override
            public void onPageSelected(int i) {
                //这里做想做的事,没有就不声明
                Logger.d(" ----onPageSelected  "+i);
            }
        });
    
    4. magic切换和点击,item文本的改变
    commonNavigator.setAdapter(new CommonNavigatorAdapter() {

            @Override
            public int getCount() {
                return mTitleDataList == null ? 0 : mTitleDataList.size();
            }

            @Override
            public IPagerTitleView getTitleView(Context context, final int index) {
                ColorTransitionPagerTitleView colorTransitionPagerTitleView = new ColorTransitionPagerTitleView(context);
                colorTransitionPagerTitleView.setNormalColor(getResources().getColor(R.color.gray_333));
                colorTransitionPagerTitleView.setSelectedColor(getResources().getColor(R.color.blue));
                colorTransitionPagerTitleView.setText(mTitleDataList.get(index));
                colorTransitionPagerTitleView.setTextSize(16);
                colorTransitionPagerTitleView.getPaint().setFakeBoldText(false);
                colorTransitionPagerTitleView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        rvReview.setCurrentPosition(index);
                    }
                });
                return colorTransitionPagerTitleView;
            }

            @Override
            public IPagerIndicator getIndicator(Context context) {
                LinePagerIndicator indicator = new LinePagerIndicator(context);
                indicator.setMode(LinePagerIndicator.MODE_EXACTLY);
                indicator.setLineWidth(SizeUtils.dp2px(20));
                indicator.setLineHeight(SizeUtils.dp2px(3));
                indicator.setColors(getResources().getColor(R.color.blue));
                return indicator;
            }
        });
    
  1. 常规的只想要页面的切换监听,指示器自己实现。
1. rvReview.bind();

2. rvReview.setPageScollListener(new RvPagerView.PageScollListener() {
            @Override
            public void onPageSelected(int i) {
                //这里做想做的事,没有就不声明
                Logger.d(" ----onPageSelected  "+i);
            }
        });

别忘记加上依赖 api 'com.github.hackware1993:MagicIndicator:1.5.0'

自定义Rv

public class RvPagerView extends RecyclerView {
    /**
     * 不绑定MagicIndicator ,rv累计偏移值
     */
    private int transX;
    /**
     * 屏幕宽度
     */
    private int screenW;
    private PageScollListener pageScollListener;

    /**
     * 滑块滑动的百分比
     */
    float positionOffset;
    /**
     * 滑动的偏移值
     */
    int positionOffsetPixels;
    /**
     * rv累计的偏移值
     */
    private int offset;

    /**
     * MagicIndicator
     */
    MagicIndicator mMagicIndicator;

    public RvPagerView(@NonNull Context context) {
        this(context, null);
    }

    public RvPagerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RvPagerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        //配置预览界面效果
        LinearLayoutManager layoutManager2 = new LinearLayoutManager(context);
        layoutManager2.setOrientation(LinearLayoutManager.HORIZONTAL);
        this.setLayoutManager(layoutManager2);

        PagerSnapHelper snapHelper = new PagerSnapHelper();
        snapHelper.attachToRecyclerView(this);
        init();
    }


    private void init() {
        screenW = DeviceUtils.getWidth(App.getApp());
    }

    public void setCurrentPosition(int position) {
        this.smoothScrollToPosition(position);
        if (mMagicIndicator != null) {
            mMagicIndicator.onPageSelected(position);
        }
    }

    /**
     * 常规的滑动 监听
     */
    public void bind() {
        this.addOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == 0) {
                    int position = transX / screenW;
                    if (pageScollListener != null) {
                        pageScollListener.onPageSelected(position);
                    }
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                transX += dx;
            }
        });
    }

    /**
     * 绑定  MagicIndicator的滑动 监听
     */
    public void bind(final MagicIndicator magicIndicator) {
        mMagicIndicator = magicIndicator;
        this.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                Logger.d("-----newState : " + newState);
                magicIndicator.onPageScrollStateChanged(newState);
                if (newState == 0 && positionOffset == 0) {
                    int position = offset / screenW;
                    Logger.d("-----  " + position);
                    magicIndicator.onPageSelected(position);
                    magicIndicator.onPageScrolled(position, 0, 0);


                    if (pageScollListener != null) {
                        pageScollListener.onPageSelected(position);
                    }
                }


            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                offset += dx;

                int mOffset = offset % screenW;
                int position = offset / screenW;
                positionOffset = (float) mOffset / (float) screenW;
                positionOffsetPixels = mOffset;
                magicIndicator.onPageScrolled(position, positionOffset, positionOffsetPixels == screenW ? 0 : positionOffsetPixels);

            }
        });
    }

    public void setPageScollListener(PageScollListener pageScollListener) {
        this.pageScollListener = pageScollListener;
    }

    public interface PageScollListener {
        void onPageSelected(int i);
    }

}