要考虑两方面的交互:
1.RecyclerView滚动到必定位置,TabLayout须要指示到对应的选项
2.TabLayout点击对应的选项菜单,RecyclerView要滚动到指定位置java
2019秋招必备面试题汇总+阿里P6P7安卓进阶资料分享面试
//滚动显示顶部菜单栏,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 对象,避免内存泄露。其中的工具
//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