商品詳情頁RecyclerView與TabLayout的聯動定位

要考慮兩方面的交互:
1.RecyclerView滾動到必定位置,TabLayout須要指示到對應的選項
2.TabLayout點擊對應的選項菜單,RecyclerView要滾動到指定位置java

  • 因爲系統原生TabLayout沒法知足指示器圓角且和字同樣寬的需求,因此個人TabLayout使用的是 MagicIndicator

2019秋招必備面試題彙總+阿里P6P7安卓進階資料分享面試

1.監聽RecyclerView的滾動事件

      //滾動顯示頂部菜單欄,onScrollStateChanged執行優先於onScrolled方法
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                switch (newState) {
                    case RecyclerView.SCROLL_STATE_IDLE://滾動中止
                        if (isClickTab)myHandler.sendEmptyMessage(1);
                        else myHandler.sendEmptyMessage(0);
                        break;
                    case RecyclerView.SCROLL_STATE_DRAGGING://手指 拖動
                        break;
                    case RecyclerView.SCROLL_STATE_SETTLING://慣性滾動
                        break;
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                scrollHeight += dy; //滑動的距離
                //滾動距離和導航欄高度算出透明度,實現上滑隱藏,下滑漸現
                float alp = (float) scrollHeight / (float) DpPxUtils.dp2px(80);
                mBinding.layoutMenu.setAlpha(alp);
            }
        });

當RecyclerView滾動中止時:咱們使用Handler來進行通知TabLayout來選定對應選項。同時咱們還經過isClickTab參數來屏蔽掉點擊TabLayout致使的滾動,其中的myHandler爲:ide

class MyHandler extends Handler {
        private WeakReference<Activity> reference;
        public MyHandler(Activity activity) {
            reference = new WeakReference<Activity>(activity);
        }
        @Override
        public void handleMessage(Message msg) {
            if (reference.get() != null) {
                switch (msg.what) {
                    case 0:
                        //中止位置爲【商品】
                        if (scrollHeight <= topBannerAndInfoHeight) {
                            mBinding.magicIndicator.onPageSelected(0);
                        //中止位置爲【詳情】
                        } else if (scrollHeight > topBannerAndInfoHeight && scrollHeight <= topGoodsPicHeight) {
                            mBinding.magicIndicator.onPageSelected(1);
                        //中止位置爲【喜歡】
                        } else {
                            mBinding.magicIndicator.onPageSelected(2);
                        }
                        break;
                    case 1://若是是點擊的tab,不從新選擇選項卡
                        isClickTab=false;
                        break;
                }
            }
        }
    }

這裏咱們使用弱引用的方式建立Handler 對象,避免內存泄露。其中的工具

  • magicIndicator:頂部指示器。
  • topBannerAndInfoHeight:商品高度
  • topGoodsPicHeight:詳情高度

2.點擊TabLayout讓RecyclerView滾動到指定位置

       //tabLayout和RecyclerView聯動事件
        String[] names = new String[]{"商品", "詳情", "喜歡"};
        TabCreateUtils.setWhiteTab(_mActivity, magicIndicator, names, index -> {
            if (scrollHeight == 0) return;
            isClickTab=true;
            switch (index) {
                case 0://商品
                    mBinding.recyclerView.smoothScrollToPosition(0);
                    break;
                case 1://詳情
                    int y = topBannerAndInfoHeight - scrollHeight;
                    mBinding.recyclerView.smoothScrollBy(0, y);
                    break;
                case 2://推薦
                    mBinding.recyclerView.smoothScrollToPosition(3);
                    break;
            }
        });

因爲magicIndicator建立指示器包含了固定的大量代碼,我封裝了一個工具類來建立,並把點擊事件傳遞出來。TabCreateUtils工具類以下:佈局

//菜單指示器建立工具類
public class TabCreateUtils {
    public interface onTitleClickListener{
        void onTitleClick(int index);
    }
    public static void setWhiteTab(Context context,MagicIndicator magicIndicator, String[] tabNames ,onTitleClickListener listener) {
        FragmentContainerHelper mFragmentContainerHelper = new FragmentContainerHelper();
        CommonNavigator commonNavigator = new CommonNavigator(context);
        commonNavigator.setAdapter(new CommonNavigatorAdapter() {
            @Override
            public int getCount() {
                return tabNames == null ? 0 : tabNames.length;
            }

            @Override
            public IPagerTitleView getTitleView(Context context, final int index) {
                SelectBigPagerTitleView colorTransitionPagerTitleView = new SelectBigPagerTitleView(context);
                colorTransitionPagerTitleView.setNormalColor(ContextCompat.getColor(context, R.color.white));
                colorTransitionPagerTitleView.setSelectedColor(ContextCompat.getColor(context, R.color.white));
                colorTransitionPagerTitleView.setText(tabNames[index]);
                colorTransitionPagerTitleView.setOnClickListener(view -> {
                    mFragmentContainerHelper.handlePageSelected(index);
                    if (listener!=null)listener.onTitleClick(index);
                });
                return colorTransitionPagerTitleView;
            }

            @Override
            public IPagerIndicator getIndicator(Context context) {
                LinePagerIndicator indicator = new LinePagerIndicator(context);
                indicator.setMode(LinePagerIndicator.MODE_WRAP_CONTENT);
                indicator.setColors(ContextCompat.getColor(context, R.color.white));
                indicator.setRoundRadius(3);
                return indicator;
            }
        });
        commonNavigator.setAdjustMode(true);
        magicIndicator.setNavigator(commonNavigator);
        mFragmentContainerHelper.attachMagicIndicator(magicIndicator);
    }
}

其中SelectBigPagerTitleView就是讓選中的字體變大,代碼以下:字體

public class SelectBigPagerTitleView extends ColorTransitionPagerTitleView {
    public SelectBigPagerTitleView(Context context) {
        super(context);
    }
    @Override
    public void onSelected(int index, int totalCount) {
       setTextSize(16);
    }
    @Override
    public void onDeselected(int index, int totalCount) {
        setTextSize(14);
    }
}

佈局文件也很簡單,就是頂部一坨菜單,底部一坨操做,中間就是RecyclerViewspa

最後的效果圖:3d

滾動到指定位置, tab變
2019秋招必備面試題彙總+阿里P6P7安卓進階資料分享code

相關文章
相關標籤/搜索