第一次写博客,我是一名Android的小码农写代码也有三四年了。有点好玩的跟大家分享一下
项目对商品详情页改版有新需求。顶部是一个渐变的Title包括“宝贝”,“详情”,“推荐”三个文本,下边是一个竖向滑动的列表显示商品详情和推荐商品。要求两部分关联起来,也就是点横向的文本下边的列表能滑动到相应item,相反亦然。
自然而然我就想到了 TabLayout + ListView实现(RecyclerView原理都是一样的)。
我贴出关键的代码:
1).向tabLayout中添加tab
for (int i = 0; i < 3; i++) { String text = null; switch (i) { case 0: text = "宝贝"; break; case 1: text = "详情"; break; case 2: text = "推荐"; break; } SpannableStringBuilder textC = new SpannableStringBuilder(text); textC.setSpan(new ForegroundColorSpan(Color.BLACK), 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); textC.setSpan(new AbsoluteSizeSpan(22, true), 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); tabLayout.addTab(tabLayout.newTab().setText(textC), i, i == 0); }
2).添加tabLayout监听,选中一项后是listview滑动到相应的item。
这里需要注意的一点是,一种触发回调的是用户点击了tab,另一种是滑动listview利用反射触发的这个回调
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(final TabLayout.Tab tab) { if (isInv) { return; } listView.post(new Runnable() { @Override public void run() { int position = 0; switch (tab.getPosition()) { case 0: position = 0; break; case 1: position = 1; break; case 2: position = adapter.imgCount; break; } listView.requestFocusFromTouch();//获取焦点 // 保存当前第一个可见的item的索引和偏移量 int height = CommonUtils.dip2px(ProductDetailActivity.this, PreferencesUtils.getInt(ProductDetailActivity.this, AppConst.STATUS_BAR, 48)); listView.setSelectionFromTop(position, height); } }); } @Override public void onTabUnselected(TabLayout.Tab tab) { } @Override public void onTabReselected(TabLayout.Tab tab) { } });
3).listview滑动监听
/* * ListView滚动距离 */ @Override public void scrollYDistance(AbsListView view, int distance, int firstVisibleItem, int visibleItemCount, int totalItemCount) { super.scrollYDistance(view, distance, firstVisibleItem, visibleItemCount, totalItemCount);
//做通栏适配,title是覆盖在listview上面firstVisibleItem可能被title遮挡住不能显示,其实为第一个可见的item
if (firstVisibleItem == 0 || firstVisibleItem == adapter.imgCount - 1) { if (listView.getChildAt(0).getBottom() < titleHeight) { return; } }
RecommendProductBean item = (RecommendProductBean) adapter.getItem(firstVisibleItem); //0:商品详情图片; 1:推荐item; 2:商品详情title; 3:推荐位title if (distance < Enums.SCREEN_HEIGHT_TO_PX - 100) { if (currentIndex == 0) { return; } currentIndex = 0; } else { Logger.e("item.getItemType().... " + item.getItemType()); switch (item.getItemType()) { case 0: case 2: if (currentIndex == 1) { return; } currentIndex = 1; break; case 1: case 3: if (currentIndex == 2) { return; } currentIndex = 2; break; default: return; } } try { isInv = true; Class clz = tabLayout.getClass(); Method animateToTab = clz.getDeclaredMethod("selectTab", new Class[]{TabLayout.Tab.class}); animateToTab.setAccessible(true); animateToTab.invoke(tabLayout, new Object[]{tabLayout.getTabAt(currentIndex)}); isInv = false; } catch (Exception e) { e.printStackTrace(); isInv = false; } }