本文為菜鳥窩作者劉婷的連載。”商城項目實戰”系列來聊聊仿”京東淘寶的購物商城”如何實現。
還記得商城項目的首頁模塊嗎,上面是滾動的炫酷輪播廣告,下面是商品活動分類,不記得話就看下效果圖,就明白了。

在下面部分的商品活動分類中,點擊任意商品項,就可以跳轉到活動商品列表頁面去,先來看下活動商品列表的界面。

這個界面很簡單,上部三個分類,為默認、價格和銷量,然后就是顯示總共多少商品數,以及一個顯示商品的列表,這個界面的實現,也就是本文的關鍵,使用 TabLayout 來實現商品排序的功能。
TabLayout 的介紹
TabLayout 是 Android Support Design 中的其中一個控件,有了它,可以輕松實現滑動標簽頁的效果,也是受到廣大開發者的喜愛。
1. TabLayout 的相關屬性
要了解 TabLayout 的相關屬性,就要知道它的相應的 Style 源碼,開發者可以通過自定義 Style 來改變 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,所以它相關的屬性也主要是 Tab 的屬性。從上面的源碼中可以看下, TabLayout 的 Tab 的背景、最大寬度、位置模式等都是可以通過自定義來調整和修改的,十分靈活。
2. TabLayout 的基本用法
TabLayout 的主要組成是 Tab,它的基本用法也就和 Tab 有關了,也很簡單,但是記住 TabLayout 是 Android Support Design 中的控件,所以必須要添加對 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 以及事件的監聽,先來看下 Tab 的添加。
TabLayout.Tab tab = tabLayout.newTab();
tab.setText(getResources().getString(R.string.default_campaign));
tab.setTag(TAG_DEFAULT);
tabLayout.addTab(tab);
先 new 一個 Tab ,然后給對應的 Tab 添加文字、tag等屬性,最后添加到 TabLayout 中。
而至于 TabLayout 的監聽事件就更加簡單了,直接調用 API 接口就好,這里就展示下最常用的 Tab 選擇事件監聽。
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
//Tab 被選擇時的處理
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
//Tab 未被選擇的處理
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
//Tab 重新被選擇的處理
}
});
已經對 TabLayout 做了簡單的介紹了,也已經對 TabLayout 有了一定的認識,言歸正傳,下面開始詳細講解如何使用 TabLayout 實現商品排序功能。
TabLayout 實現商品排序功能
活動商品列表界面中商品會根據上面的默認、銷售和價格三個 Tab 的選擇情況來確定怎樣的排序方法,然后將商品展示在列表中,同時列表上面的還會顯示總的商品數量,如何實現呢?往下看。
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'
}
商城項目開發到這里,build.gradle 中依賴也越來越多了。
2. 添加權限
權限的添加就不用多解釋了啊,這里是網絡數據請求,自然要網絡權限,加上圖片的顯示需要緩存,所以需要的權限也就是網絡權限和寫的權限。
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
權限加好了,就可以開始動工設計界面了。
3. 自定義 TabLayout 的樣式
自定義 TabLayout 的 Style,命名為 customTabLayout,擴展于 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 的自定義樣式可以根據實際情況進行調整。
4. 添加活動商品主界面布局
上文效果圖中可以看到的是上部的 Toolbar、可滑動的標簽頁、顯示商品總數的文本以及顯示商品的列表,這個列表也要可以下拉刷新和上拉加載更多。
<?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>
因為列表也要可以下拉刷新和上拉加載更多,所以就還是使用之前的 MaterialRefreshLayout 下拉刷新和上拉加載更多的控件。
而商品列表的 item 布局和之前寫好的熱門商品列表 item 布局是一樣的,另外商品屬性也一致,這里就直接請參考文章《商城項目實戰 | 8.2 SwipeRefreshLayout 實現可以下拉刷新和加載更多的熱門商品列表》,這里就不多廢話了。
5. 初始化 TabLayout
在活動商品列表的 Activity 中初始化 TabLayout,也就是要初始化 Tab。
TabLayout.Tab tab = tabLayout.newTab();
tab.setText("默認");
tab.setTag(TAG_DEFAULT);
tabLayout.addTab(tab);
tab = tabLayout.newTab();
tab.setText("價格");
tab.setTag(TAG_PRICE);
tabLayout.addTab(tab);
tab = tabLayout.newTab();
tab.setText("銷量");
tab.setTag(TAG_SALE);
tabLayout.addTab(tab);
總共有默認、價格和銷量三個 Tab, new 好后,添加到 TabLayout,初始化就寫好了。
6. 添加事件監聽
選擇上部不同的 Tab 項,下面的商品列表就會相應改變排序,就要為 TabLayout 添加 setOnTabSelectedListener() Tab 選擇事件監聽。
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 則是分頁工具類,在文章《商城項目實戰 | 15.1 實現分頁工具類的封裝》中已經有詳細說明,recyclerView 則是列表。這里實現的就是改變排序方式,然后刷新列表,并且列表滑動到最頂部。
效果圖
碼完了所有的代碼,最后就是看效果的時候啊。

效果我們基本上都已經實現了,不過有大家應該也注意到了在最上面 Toolbar 的右側,也就是標題的右側有個網格的圖標,這個圖標是用來干什么的呢?那是用來實現商品列表 list 和 grid 模式切換的,如何實現呢?請繼續關注,在下篇文章中將著重介紹。
擼這個項目的一半,你就是大神 , 戳http://mp.weixin.qq.com/s/ZagocTlDfxZpC2IjUSFhHg