仿淘寶商品詳情頁TabLayout+ListView
阿新 • • 發佈:2019-01-04
第一次寫部落格,我是一名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; } }