1. 程式人生 > >仿淘寶商品詳情頁TabLayout+ListView

仿淘寶商品詳情頁TabLayout+ListView

第一次寫部落格,我是一名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;
    }

}