商品详情页RecyclerView与TabLayout的联动定位
source link: http://mp.weixin.qq.com/s?__biz=MzIxNzU1Nzk3OQ%3D%3D&%3Bmid=2247489270&%3Bidx=1&%3Bsn=72e4752338037045aee4612c99409831
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
code小生 ,一个专注大前端领域的技术平台
公众号回复 Android 加入我的技术群
作者: Small_Cake
链接: https://www.jianshu.com/p/5df93040e126
声明: 本文已获Small_Cake
授权发表,转发等请联系原作者授权
要考虑两方面的交互:
1.RecyclerView滚动到一定位置,TabLayout需要指示到对应的选项
2.TabLayout点击对应的选项菜单,RecyclerView要滚动到指定位置
-
由于系统原生TabLayout无法满足指示器圆角且和字一样宽的需求,所以我的TabLayout使用的是 MagicIndicator
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为:
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); } }
布局文件也很简单,就是顶部一坨菜单,底部一坨操作,中间就是RecyclerView
image.png最后的效果图:
滚动到指定位置, tab变
原文链接: https://www.jianshu.com/p/5df93040e126
扫一扫 关注我的公众号
如果你想要跟大家分享你的文章,欢迎投稿~
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK