商城項(xiàng)目實(shí)戰(zhàn) | 16.1 TabLayout 實(shí)現(xiàn)商品排序功能

本文為菜鳥(niǎo)窩作者劉婷的連載。”商城項(xiàng)目實(shí)戰(zhàn)”系列來(lái)聊聊仿”京東淘寶的購(gòu)物商城”如何實(shí)現(xiàn)。

還記得商城項(xiàng)目的首頁(yè)模塊嗎,上面是滾動(dòng)的炫酷輪播廣告,下面是商品活動(dòng)分類,不記得話就看下效果圖,就明白了。

首頁(yè)
首頁(yè)

在下面部分的商品活動(dòng)分類中,點(diǎn)擊任意商品項(xiàng),就可以跳轉(zhuǎn)到活動(dòng)商品列表頁(yè)面去,先來(lái)看下活動(dòng)商品列表的界面。

商品列表
商品列表

這個(gè)界面很簡(jiǎn)單,上部三個(gè)分類,為默認(rèn)、價(jià)格和銷量,然后就是顯示總共多少商品數(shù),以及一個(gè)顯示商品的列表,這個(gè)界面的實(shí)現(xiàn),也就是本文的關(guān)鍵,使用 TabLayout 來(lái)實(shí)現(xiàn)商品排序的功能。

TabLayout 的介紹

TabLayout 是 Android Support Design 中的其中一個(gè)控件,有了它,可以輕松實(shí)現(xiàn)滑動(dòng)標(biāo)簽頁(yè)的效果,也是受到廣大開(kāi)發(fā)者的喜愛(ài)。

1. TabLayout 的相關(guān)屬性

要了解 TabLayout 的相關(guān)屬性,就要知道它的相應(yīng)的 Style 源碼,開(kāi)發(fā)者可以通過(guò)自定義 Style 來(lái)改變 TabLayout 的樣式和屬性。

<style name="Widget.Design.TabLayout" parent="Base.Widget.Design.TabLayout">
        <item name="tabGravity">fill</item>
        <item name="tabMode">fixed</item>
    </style>

<style name="Base.Widget.Design.TabLayout" parent="android:Widget">
        <item name="tabMaxWidth">@dimen/design_tab_max_width</item>
        <item name="tabIndicatorColor">?attr/colorAccent</item>
        <item name="tabIndicatorHeight">2dp</item>
        <item name="tabPaddingStart">12dp</item>
        <item name="tabPaddingEnd">12dp</item>
        <item name="tabBackground">?attr/selectableItemBackground</item>
        <item name="tabTextAppearance">@style/TextAppearance.Design.Tab</item>
        <item name="tabSelectedTextColor">?android:textColorPrimary</item>
</style>

TabLayout 的主要組成就是 Tab,所以它相關(guān)的屬性也主要是 Tab 的屬性。從上面的源碼中可以看下, TabLayout 的 Tab 的背景、最大寬度、位置模式等都是可以通過(guò)自定義來(lái)調(diào)整和修改的,十分靈活。

2. TabLayout 的基本用法

TabLayout 的主要組成是 Tab,它的基本用法也就和 Tab 有關(guān)了,也很簡(jiǎn)單,但是記住 TabLayout 是 Android Support Design 中的控件,所以必須要添加對(duì) Android Support Design 的依賴,這里是在 build.gradle 中添加依賴。

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.2.0'
    compile 'com.android.support:design:25.2.0'
}

然后先在 xml 文件中添加 TabLayout。

<android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >

</android.support.design.widget.TabLayout>

最后就是要添加 Tab 以及事件的監(jiān)聽(tīng),先來(lái)看下 Tab 的添加。

TabLayout.Tab tab = tabLayout.newTab();
tab.setText(getResources().getString(R.string.default_campaign));
tab.setTag(TAG_DEFAULT);

tabLayout.addTab(tab);

先 new 一個(gè) Tab ,然后給對(duì)應(yīng)的 Tab 添加文字、tag等屬性,最后添加到 TabLayout 中。

而至于 TabLayout 的監(jiān)聽(tīng)事件就更加簡(jiǎn)單了,直接調(diào)用 API 接口就好,這里就展示下最常用的 Tab 選擇事件監(jiān)聽(tīng)。

 tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                    //Tab 被選擇時(shí)的處理
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                   //Tab 未被選擇的處理
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                     //Tab 重新被選擇的處理
            }
        });

已經(jīng)對(duì) TabLayout 做了簡(jiǎn)單的介紹了,也已經(jīng)對(duì) TabLayout 有了一定的認(rèn)識(shí),言歸正傳,下面開(kāi)始詳細(xì)講解如何使用 TabLayout 實(shí)現(xiàn)商品排序功能。

TabLayout 實(shí)現(xiàn)商品排序功能

活動(dòng)商品列表界面中商品會(huì)根據(jù)上面的默認(rèn)、銷售和價(jià)格三個(gè) Tab 的選擇情況來(lái)確定怎樣的排序方法,然后將商品展示在列表中,同時(shí)列表上面的還會(huì)顯示總的商品數(shù)量,如何實(shí)現(xiàn)呢?往下看。

1. Gradle 添加依賴

既然使用了 TabLayout,那么首先就是要添加 Android Support Design 的依賴,在 build.gradle 中添加。

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.2.0'
    compile 'com.android.support.constraint:constraint-layout:1.0.1'
    testCompile 'junit:junit:4.12'
    compile 'com.daimajia.slider:library:1.1.5@aar'
    compile 'com.squareup.picasso:picasso:2.5.2'
    compile 'com.nineoldandroids:library:2.4.0'
    compile 'com.android.support:support-v4:25.2.0'
    compile 'com.android.support:recyclerview-v7:25.2.0'
    compile 'com.android.support:cardview-v7:25.2.0'
    compile 'com.squareup.okhttp3:okhttp:3.6.0'
    compile 'com.google.code.gson:gson:2.8.0'
    compile 'com.github.d-max:spots-dialog:0.7'
    compile 'com.facebook.fresco:fresco:1.2.0'
    compile 'com.cjj.materialrefeshlayout:library:1.3.0'
    compile 'org.xutils:xutils:3.5.0'
    compile 'com.android.support:design:25.2.0'
}

商城項(xiàng)目開(kāi)發(fā)到這里,build.gradle 中依賴也越來(lái)越多了。

2. 添加權(quán)限

權(quán)限的添加就不用多解釋了啊,這里是網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求,自然要網(wǎng)絡(luò)權(quán)限,加上圖片的顯示需要緩存,所以需要的權(quán)限也就是網(wǎng)絡(luò)權(quán)限和寫的權(quán)限。

 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>

權(quán)限加好了,就可以開(kāi)始動(dòng)工設(shè)計(jì)界面了。

3. 自定義 TabLayout 的樣式

自定義 TabLayout 的 Style,命名為 customTabLayout,擴(kuò)展于 Widget.Design.TabLayout 的 Style。

<style name="customTabLayout" parent="Widget.Design.TabLayout">
        <!--<item name="tabMaxWidth">@dimen/tab_max_width</item>-->
        <item name="tabIndicatorColor">#eb4f38</item>
        <item name="tabIndicatorHeight">2dp</item>
        <item name="tabPaddingStart">12dp</item>
        <item name="tabPaddingEnd">12dp</item>
        <item name="tabBackground">@color/white</item>
        <item name="tabTextAppearance">@style/customTabTextAppearance</item>
        <item name="tabSelectedTextColor">#eb4f38</item>
    </style>

TabLayout 的自定義樣式可以根據(jù)實(shí)際情況進(jìn)行調(diào)整。

4. 添加活動(dòng)商品主界面布局

上文效果圖中可以看到的是上部的 Toolbar、可滑動(dòng)的標(biāo)簽頁(yè)、顯示商品總數(shù)的文本以及顯示商品的列表,這個(gè)列表也要可以下拉刷新和上拉加載更多。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/bg_color">

    <com.liuting.cniao_shop.widget.CNiaoToolbar
        android:id="@id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        app:isShowSearchView="false"
        app:navigationIcon="@mipmap/ic_back"
        app:contentInsetEnd="56dp"
        app:title="@string/product_list">

    </com.liuting.cniao_shop.widget.CNiaoToolbar>

    <android.support.design.widget.TabLayout
        android:id="@+id/ware_tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="@style/customTabLayout"
        app:tabGravity="fill"
        app:tabMode="fixed"
        >

    </android.support.design.widget.TabLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:minHeight="30dp"
        android:gravity="center_vertical"
        android:padding="5dp"
        android:background="@color/gold_yellow">

        <TextView
            android:id="@+id/ware_tv_summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/gray"/>

    </LinearLayout>

    <com.cjj.MaterialRefreshLayout
        android:id="@+id/ware_refresh_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:overlay="false"
        app:wave_show="false"
        app:wave_color="#90ffffff"
        app:progress_colors="@array/material_colors"
        app:wave_height_type="higher"
        >

        <android.support.v7.widget.RecyclerView
            android:id="@+id/ware_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        </android.support.v7.widget.RecyclerView>

    </com.cjj.MaterialRefreshLayout>

</LinearLayout>

因?yàn)榱斜硪惨梢韵吕⑿潞蜕侠虞d更多,所以就還是使用之前的 MaterialRefreshLayout 下拉刷新和上拉加載更多的控件。

而商品列表的 item 布局和之前寫好的熱門商品列表 item 布局是一樣的,另外商品屬性也一致,這里就直接請(qǐng)參考文章《商城項(xiàng)目實(shí)戰(zhàn) | 8.2 SwipeRefreshLayout 實(shí)現(xiàn)可以下拉刷新和加載更多的熱門商品列表》,這里就不多廢話了。

5. 初始化 TabLayout

在活動(dòng)商品列表的 Activity 中初始化 TabLayout,也就是要初始化 Tab。

TabLayout.Tab tab = tabLayout.newTab();
        tab.setText("默認(rèn)");
        tab.setTag(TAG_DEFAULT);

        tabLayout.addTab(tab);

        tab = tabLayout.newTab();
        tab.setText("價(jià)格");
        tab.setTag(TAG_PRICE);

        tabLayout.addTab(tab);

        tab = tabLayout.newTab();
        tab.setText("銷量");
        tab.setTag(TAG_SALE);

        tabLayout.addTab(tab);

總共有默認(rèn)、價(jià)格和銷量三個(gè) Tab, new 好后,添加到 TabLayout,初始化就寫好了。

6. 添加事件監(jiān)聽(tīng)

選擇上部不同的 Tab 項(xiàng),下面的商品列表就會(huì)相應(yīng)改變排序,就要為 TabLayout 添加 setOnTabSelectedListener() Tab 選擇事件監(jiān)聽(tīng)。

tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                    orderBy = (int) tab.getTag();
                    pager.putParam("orderBy", orderBy);
                    pager.refresh();
                    recyclerView.scrollToPosition(0);
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                   //Tab 未被選擇的處理
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                     //Tab 重新被選擇的處理
            }
        });

orderBy 為排序方式,pager 則是分頁(yè)工具類,在文章《商城項(xiàng)目實(shí)戰(zhàn) | 15.1 實(shí)現(xiàn)分頁(yè)工具類的封裝》中已經(jīng)有詳細(xì)說(shuō)明,recyclerView 則是列表。這里實(shí)現(xiàn)的就是改變排序方式,然后刷新列表,并且列表滑動(dòng)到最頂部。

效果圖

碼完了所有的代碼,最后就是看效果的時(shí)候啊。

效果
效果

效果我們基本上都已經(jīng)實(shí)現(xiàn)了,不過(guò)有大家應(yīng)該也注意到了在最上面 Toolbar 的右側(cè),也就是標(biāo)題的右側(cè)有個(gè)網(wǎng)格的圖標(biāo),這個(gè)圖標(biāo)是用來(lái)干什么的呢?那是用來(lái)實(shí)現(xiàn)商品列表 list 和 grid 模式切換的,如何實(shí)現(xiàn)呢?請(qǐng)繼續(xù)關(guān)注,在下篇文章中將著重介紹。

擼這個(gè)項(xiàng)目的一半,你就是大神 , 戳http://mp.weixin.qq.com/s/ZagocTlDfxZpC2IjUSFhHg

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容