IT之家

Android两种方式实现横向滚动图标+指示器

2020-05-04  本文已影响0人  提莫熊猫侠

啊哈,先上应用效果图,符合你的需求,你再继续看这篇博文哈~

类型1 :RecyclerView实现非分页效果的左右滑动
类型2 :ViewPager+RecyclerView实现分页效果的左右滑动

20200428102813654.gif

GitHub地址 : https://github.com/xiaoyaomeng/TopicView/tree/master

类型1:RecyclerView实现非分页效果的左右滑动

private void initTypeRecyclerView(int rowNum) {
        final RecyclerView topicRecyclerView = findViewById(R.id.topicRecyclerView);
        final View mIndicatorLayout = findViewById(R.id.parent_layout);
        final View mIndicatorView = findViewById(R.id.main_line);

        TopicAdapter topicAdapter = new TopicAdapter(getApplicationContext(), mTopicData);
        topicAdapter.setOnItemClickListener(this);

        topicRecyclerView.setAdapter(topicAdapter);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(getApplicationContext(), rowNum);
        gridLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

        topicRecyclerView.setLayoutManager(gridLayoutManager);
        topicRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);

            }

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

                //当前RcyclerView显示区域的高度。水平列表屏幕从左侧到右侧显示范围
                int extent = recyclerView.computeHorizontalScrollExtent();

                //整体的高度,注意是整体,包括在显示区域之外的。
                int range = recyclerView.computeHorizontalScrollRange();

                //已经滚动的距离,为0时表示已处于顶部。
                int offset = recyclerView.computeHorizontalScrollOffset();

                //计算出溢出部分的宽度,即屏幕外剩下的宽度
                float maxEndX = range - extent;

                //计算比例
                float proportion = offset / maxEndX;

                int layoutWidth = mIndicatorLayout.getWidth();
                int indicatorViewWidth = mIndicatorView.getWidth();

                //可滑动的距离
                int scrollableDistance = layoutWidth - indicatorViewWidth;

                //设置滚动条移动
                mIndicatorView.setTranslationX(scrollableDistance * proportion);
            }
        });

    }

类型2 :ViewPager+RecyclerView实现分页效果的左右滑动

private void initTypeViewPager(int rowNum, int columnNum) {
        final ViewPager topicViewPager = findViewById(R.id.topicViewPager);
        final MagicIndicator topicIndicator = findViewById(R.id.topicIndicator);
        //1.根据数据的多少来分页,每页的数据为rw
        int singlePageDatasNum = rowNum * columnNum; //每个单页包含的数据量:2*4=8;
        int pageNum = mTopicData.size() / singlePageDatasNum;//算出有几页菜单:20%8 = 3;
        if (mTopicData.size() % singlePageDatasNum > 0) pageNum++;//如果取模大于0,就还要多一页出来,放剩下的不满项
        ArrayList<RecyclerView> mList = new ArrayList<>();
        for (int i = 0; i < pageNum; i++) {
            RecyclerView recyclerView = new RecyclerView(getApplicationContext());
            GridLayoutManager gridLayoutManager = new GridLayoutManager(getApplicationContext(), columnNum);
            recyclerView.setLayoutManager(gridLayoutManager);
            int fromIndex = i * singlePageDatasNum;
            int toIndex = (i + 1) * singlePageDatasNum;
            if (toIndex > mTopicData.size()) toIndex = mTopicData.size();
            //a.截取每个页面包含数据
            ArrayList<TopicBean> menuItems = new ArrayList<TopicBean>(mTopicData.subList(fromIndex, toIndex));
            //b.设置每个页面的适配器数据
            TopicAdapter menuAdapter = new TopicAdapter(getApplicationContext(), menuItems);
            menuAdapter.setOnItemClickListener(this);
            //c.绑定适配器,并添加到list
            recyclerView.setAdapter(menuAdapter);
            mList.add(recyclerView);
        }
        //2.ViewPager的适配器
        HomeTopicPagerAdapter menuViewPagerAdapter = new HomeTopicPagerAdapter(mList);
        topicViewPager.setAdapter(menuViewPagerAdapter);
        //3.动态设置ViewPager的高度,并加载所有页面
        int height = dp2px(getApplicationContext(), 76.0f);//这里的80为MainMenuAdapter中布局文件高度
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, mTopicData.size() <= columnNum ? height : height * rowNum);
        topicViewPager.setLayoutParams(layoutParams);
        topicViewPager.setOffscreenPageLimit(pageNum - 1);

        //4.创建指示器
        CommonNavigator commonNavigator = new CommonNavigator(getApplicationContext());
        commonNavigator.setAdjustMode(true);
        final int finalPageNum = pageNum;

        commonNavigator.setAdapter(new CommonNavigatorAdapter() {
            @Override
            public int getCount() {
                return finalPageNum;
            }

            @Override
            public IPagerTitleView getTitleView(Context context, int index) {
                return new DummyPagerTitleView(context);
            }

            @Override
            public IPagerIndicator getIndicator(Context context) {
                LinePagerIndicator indicator = new LinePagerIndicator(context);
                indicator.setMode(LinePagerIndicator.MODE_EXACTLY);
                indicator.setLineHeight(UIUtil.dip2px(context, 3));//就是指示器的高
                indicator.setLineWidth(UIUtil.dip2px(context, 66 / finalPageNum));//就是指示器的宽度,然后通过页数来评分
                indicator.setRoundRadius(UIUtil.dip2px(context, 3));
                indicator.setStartInterpolator(new AccelerateInterpolator());
                indicator.setEndInterpolator(new DecelerateInterpolator(3));
                indicator.setColors(ContextCompat.getColor(context, R.color.colorAccent));
                return indicator;
            }
        });
        //5.配置指示器,并和ViewPager产生绑定
        topicIndicator.setNavigator(commonNavigator);
        ViewPagerHelper.bind(topicIndicator, topicViewPager);
    }
上一篇下一篇

猜你喜欢

热点阅读