前言
Google官方在14年Google I/O上推出了全新的設計語言——Material Design。一並推出了一系列實現Material Design效果的控件庫——Android Design Support Library。其中,有TabLayout, NavigationView,Floating labels for editing text,Floating Action Button,Snackbar, CoordinatorLayout, CollapsingToolbarLayout等等控件。在今后的學習中,我將一一介紹它們的特點和用法。
在移動應用中切換不同場景/功能,iOS中以底部三按鈕、四按鈕來實現的,而在Android中,則是抽屜式菜單或左右滑動式設計的。如何實現類似Google Play應用商店式的左右滑動,這就得靠TabLayout來實現了。

正文
1.獲得Android Design Support Library庫:
在Gradle文件中的dependency中添加'compile 'com.android.support:design:22.2.1'依賴。
2.定義布局文件:
通過使用可知,上面那些標簽時通過TabLayout實現,而下面內容的變化則是ViewPager+Fragment實現的。
因此在MainActivity中:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
/>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#ffffff"
/>
</LinearLayout>
Fragment:
切換ViewPager,顯示不同的Fragment,在這里用一個布局相同的Fragment示例。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
/>
</LinearLayout>
3.具體實現代碼:
1)創建Fragment
public class PageFragment extends Fragment {
public static final String ARGS_PAGE = "args_page";
private int mPage;
public static PageFragment newInstance(int page) {
Bundle args = new Bundle();
args.putInt(ARGS_PAGE, page);
PageFragment fragment = new PageFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPage = getArguments().getInt(ARGS_PAGE);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_page,container,false);
TextView textView = (TextView) view.findViewById(R.id.textView);
textView.setText("第"+mPage+"頁");
return view;
}
}
2)適配器類
class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public final int COUNT = 5;
private String[] titles = new String[]{"Tab1", "Tab2", "Tab3", "Tab4", "Tab5"};
private Context context;
public MyFragmentPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.context = context;
}
@Override
public Fragment getItem(int position) {
return PageFragment.newInstance(position + 1);
}
@Override
public int getCount() {
return COUNT;
}
@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
}
相信Fragment+ViewPager+FragmentPagerAdapter的組合,大家已經用得很熟悉了,在這里我就不介紹了。
3)TabLayout的使用:
根據官方文檔說明,TabLayout的使用有以下兩種方式:
- 通過TabLayout的addTab()方法添加新構建的Tab實例到TabLayout中:
TabLayout tabLayout = ...;
tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
2.第二種則是使用ViewPager和TabLayout一站式管理Tab,也就是說不需要像第一種方式那樣手動添加Tab:
ViewPager viewPager = ...;
TabLayout tabLayout = ...;
viewPager.addOnPageChangeListener(new TabLayoutOnPageChangeListener(tabLayout));
而我們TabLayout的Demo就是用得第二種方式:
//Fragment+ViewPager+FragmentViewPager組合的使用
ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(getSupportFragmentManager(),
this);
viewPager.setAdapter(adapter);
//TabLayout
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout);
tabLayout.setupWithViewPager(viewPager);
運行效果:
效果不錯,但是TabLayout中的Tab似乎沒有占滿屏幕的寬度。如何解決呢?
有代碼和XML兩種方式:
1).代碼
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
2).XML布局文件
<android.support.design.widget.TabLayout
android:id="@+id/tabLayout"
app:tabGravity="fill"
app:tabMode="fixed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
下面就來解釋一下TabGravity和TabMode,
TabGravity:放置Tab的Gravity,有GRAVITY_CENTER 和 GRAVITY_FILL兩種效果。顧名思義,一個是居中,另一個是盡可能的填充(注意,GRAVITY_FILL需要和MODE_FIXED一起使用才有效果)
TabMode:布局中Tab的行為模式(behavior mode),有兩種值:MODE_FIXED 和 MODE_SCROLLABLE。
MODE_FIXED:固定tabs,並同時顯示所有的tabs。
MODE_SCROLLABLE:可滾動tabs,顯示一部分tabs,在這個模式下能包含長標簽和大量的tabs,最好用於用戶不需要直接比較tabs。
下面用代碼來比較這兩種模式的不同:
class MyFragmentPagerAdapter extends FragmentPagerAdapter {
//tabs的數據集
public final int COUNT = 10;
private String[] titles = new String[]{"Tab2221", "T2", "Tb3", "Tab4", "Tab5555555555","Tab2221", "T2", "Tb3", "Tab4", "Tab5555555555"};
...
}
//1.MODE_SCROLLABLE模式
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
//2.MODE_FIXED模式
tabLayout.setTabMode(TabLayout.MODE_FIXED);
1.MODE_SCROLLABLE模式
2.MODE_FIXED模式