TabLayout和RecyclerView结合,点击TabLayout会切换到对应的RecyclerView位置,滚动RecyclerView时TabLayout会跟着切换到对应位置。

转载请标明出处:https://blog.csdn.net/m0_38074457/article/details/85120375,本文出自【陈少华的博客】

一、效果图

二、实现原理

TabLayout和RecyclerView结合,点击TabLayout会切换到对应的RecyclerView位置,滚动RecyclerView时TabLayout会跟着切换到对应位置。_第1张图片

1、页面布局从上到下为:顶部的“title”->title下面隐藏的tablayout(mainTab)->最底部的recycle人view,其中recycleview包含 1)自己的头部、2)头部下面的tablayout(tvTab) 、3)item。

2、计算mainTab在屏幕中的坐标位置,计算滑动过程中rv中的tab在屏幕中的位置,使当rv中tab从下到上滑动到页面title底部的时候使mainTab可见,使当rv中的tab从上到下滑出title底部时候使mainTab隐藏。

3、页面中的tab代表属性值和rv中的item使对应的,rv滑动过程中获取页面中可见的第一个item的属性值,然后和两个tab进行匹配,当可见的第一个item的属性值发生变化时候切换tab到对应的一个属性值的tab。

4、当点击mainTab或者rv中的tab时候,获取点击的tab属性值,找到含有此属性值最靠前得rv中对应的一个item,然后是rv滑动到对应的位置即可。

三、实现代码

1、页面布局




    

        

        
        

    

    
    

    

        
        

        

    


二、计算rv中的tablayout在屏幕中的位置,和页面中的tablayout的屏幕中的位置

    //获取页面标题mLlHomeTitle在屏幕中的位置
    private void getTitleXY() {
        mLlHomeTitle.getLocationOnScreen(mLocationTitle);
        titleX = mLocationTitle[0];
        titleY = mLocationTitle[1];
    }

    //获取RecyclerView中的TabLayout在屏幕中的位置
    private void getRvTabXY() {
        if (mHolderTabLayout != null) {
            mHolderTabLayout.mLlTlHome.getLocationOnScreen(mLocationRvTab);
            rvTabX = mLocationRvTab[0];
            rvTabY = mLocationRvTab[1];
        }
    }

3、监听rv的滑动过程,获取第一个可见的item属性,然后切换其他两个tab的位置

//recyclerview的滑动监听
        mRvHome.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                //获取标题在屏幕中的的位置
                getTitleXY();
                //获取RecyclerView的tablayout在屏幕中的位置
                getRvTabXY();
                int position = findFirstVisibleItem();
                //
                if (rvTabY > 0) {
                    int height = mLlHomeTitle.getHeight();
                    if (rvTabY <= titleY + height) {
                        mLlMainTablayout.setVisibility(View.VISIBLE);
                    } else {
                        mLlMainTablayout.setVisibility(View.INVISIBLE);
                    }
                } else {
                    if (position >= RV_HEADER_COUNT - 1) {
                        mLlMainTablayout.setVisibility(View.VISIBLE);
                    } else if (position <= RV_HEADER_COUNT - 2) {
                        mLlMainTablayout.setVisibility(View.INVISIBLE);
                    }
                }

                //这个很重要,如果true(true代表点击了页面中的tablayout,这里不需要再给页面中的tablaout做改变)
                if (stopScroll) {
                    stopScroll = false;
                    return;
                }

                //根据第一个可见的item的属性,来设置页面中的tablayout切换到哪个tab
                if (position >= RV_HEADER_COUNT) {
                    RvData bean = mRvDatas.get(position - RV_HEADER_COUNT);
                    String shortName = bean.getParentcategory().getName();
                    int selectedTabPosition = mTlMain.getSelectedTabPosition();
                    String tabText = (String) mTlMain.getTabAt(selectedTabPosition).getText();
                    if (!shortName.equals(tabText)) {
                        for (int i = 0; i < mParentCategoryList.size(); i++) {
                            String name = mParentCategoryList.get(i).getName();
                            if (shortName.equals(name)) {
                                stopChange = true;
                                mTlMain.getTabAt(i).select();
                                break;
                            }
                        }
                    }
                }
            }
        });

4、监听页面中的tablayout和rv中的tablayout,如果点击了tablayout,那么rv会滚动到对应的item位置

 //两次监听会有异常,添加监听前先删除之前的监听
        mHolderTabLayout.mTlHome.removeOnTabSelectedListener(holderListener);
        mHolderTabLayout.mTlHome.addOnTabSelectedListener(holderListener);

        mTlMain.removeOnTabSelectedListener(mainTabListener);
        mTlMain.addOnTabSelectedListener(mainTabListener);
 //recyclerview中的tablayout监听
    private TabLayout.OnTabSelectedListener holderListener = new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            int position = tab.getPosition();
            mTlMain.getTabAt(position).select();
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    };

    //页面中的tablayout的监听
    private TabLayout.OnTabSelectedListener mainTabListener = new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            //当页面中的tablayout被选中时
            //获取现在的tab选中位置
            int position = tab.getPosition();
            //使RecyclerView中的tab也切换到相同的一个位置
            mHolderTabLayout.mTlHome.getTabAt(position).select();
            //如果当前tab的位置不是第一个,那么
            if (position != 0) {
                mLlMainTablayout.setVisibility(View.VISIBLE);
            }

            //这句很关键,如果值为不能改变那么,不执行
            if (stopChange) {
                stopChange = false;
                return;
            }

            //滚动到RcyclerView对应的位置
            String text = (String) mTlMain.getTabAt(position).getText();
            for (int i = 0; i < mRvDatas.size(); i++) {
                RvData bean = mRvDatas.get(i);
                if (text.equals(bean.getParentcategory().getName())) {
                    stopScroll = true;
                    mStaggeredGridLayoutManager.scrollToPositionWithOffset
                            (RV_HEADER_COUNT + i, mLlMainTablayout.getHeight());
                    break;
                }
            }
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    };

备注:

具体实现代码我放在了github上 https://github.com/hnsycsxhzcsh/TabLayoutRV,如果对你有帮助,欢迎博客点赞支持,并在github右上角star支持!

 

 

你可能感兴趣的:(特效)