Introduction
在Material Design中,Tabs使用頁籤的方式管理不同的畫面,通常位於Toolbar的下方,常與Fragment/ViewPager搭配使用。背景的顏色通常也與Toolbar一致
![](tabs01.png)
在常見的使用中,Tabs可以被分為兩種模式
1.Fixed
在Fixed模式下,每個Tab item的大小都是一致的,也因為大小都一樣,所以在設計上通常放置兩個(含)以上,最多四個item
2.Scrollable
在Scrollable模式下,Tab item常為4個以上
在Tabs item設計上,不管是Fixed模式或是Scrollable模式,都可以用文字 / 圖案 / 文字+圖案下去設計,接下來我們來實際創建一個Tabs + ViewPager
Create a Tab Layout with Text: Fixed Mode
添加support:design library
使用TabLayout,首先需要把support:design library添加進我們的Project中,在 File -> Project Structure -> Dependencles 下新增。
![](tabs02.png)
創建TabLayout
在xml裡,創建一個TabLayout,賦予屬性app:tabMode=”fixed”,背景顏色使用跟Toolbar(colorPrimary)顏色一致,接著在下方創建ViewPager
app:tabGravity=”fill”表示tabs item會填滿整個TabLayout
layout:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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.support.v7.widget.Toolbar android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:id="@+id/toolbar_id" android:background="@color/colorPrimary" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/tabLayout_id" android:layout_below="@+id/toolbar_id" android:background="@color/colorPrimary" app:tabMode="fixed" app:tabGravity="fill"/>
<android.support.v4.view.ViewPager android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/viewPager_id" android:layout_below="@+id/tabLayout_id"/>
</RelativeLayout>
|
預覽效果如下:
![](tabs03.png)
Define layouts for the items in TabLayout
我們新增Fragment的layout,這些View,會顯示在ViewPager中,同時透過TabLayout的setupWithViewPager()方法,能夠自動產生對應ViewPager內view的tab item。
新增Fragment layout
layout:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.v7.widget.AppCompatTextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/main_item_one" android:textSize="60sp" android:textStyle="bold"/>
</RelativeLayout>
|
預覽效果如下:
![](tabs04.png)
接著依序創建layout_item_two與layout_item_three_layout,總共3個layout
![](tabs05.png)
Create Java class for item layout
接下來創建Freagment class
java:
1 2 3 4 5 6 7 8 9 10 11
| public class OneFragment extends Fragment {
private View view;
@Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { view = inflater.inflate(R.layout.layout_item_one, container, false); return view; } }
|
依序創建:
layout_item_one
layout_item_two
layout_item_three
的Fragment class
![](tabs06.png)
接下來我們創建ViewPagerAdapter,並繼承FragmentPagerAdapter
java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class ViewPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList = new ArrayList<>(); private List<String> fragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) { super(fm); }
@Override public Fragment getItem(int position) { // Fragment return fragmentList.get(position); }
@Override public int getCount() { return fragmentList.size(); }
@Nullable @Override public CharSequence getPageTitle(int position) { // 取得當前頁的title return fragmentTitleList.get(position); }
// 添加Fragment 與 Title 方法 public void addFragment(Fragment fragment, String title) { fragmentList.add(fragment); fragmentTitleList.add(title); } }
|
Setting TabLayout
在Adapter創建完成之後,回到Activity,把Fragment加進adapter,並把它與ViewPager綁定
java:
1 2 3 4 5 6 7
| ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new OneFragment(), "ITEM ONE"); adapter.addFragment(new TwoFragment(), "ITEM TWO"); adapter.addFragment(new ThreeFragment(), "ITEM THREE");
viewPager.setAdapter(adapter);
|
TabLayout有提供我們一個基於ViewPager快速創建對應Tabs的方法
java:
1 2 3
| tabLayout = findViewById(R.id.tabLayout_id);
tabLayout.setupWithViewPager(viewPager);
|
運行效果如下:
![](tabs07.gif)
改變Tab文字顏色,在TabLayout的tag裡,添加屬性
1
| app:tabTextColor="@color/colorWhite"
|
運行效果如下:
![](tabs08.gif)
改變Tab被選中的文字顏色,在TabLayout的tag裡,添加屬性
1
| app:tabSelectedTextColor="@color/colorAccent"
|
運行效果如下:
![](tabs09.gif)
改變TabLayout下方游標顏色,在TabLayout的tag裡,添加屬性
1
| app:tabIndicatorColor="@color/colorLightBlue"
|
運行效果如下:
![](tabs16.png)
改變TabLayout下方游標高度,在TabLayout的tag裡,添加屬性
1
| app:tabIndicatorHeight="10dp"
|
運行效果如下:
![](tabs17.png)
Create a Tab Layout with Text: Scrollable Mode
要創建可滑動的TabLayout,首先把屬性app:tabMode改為scrollable
1
| app:tabMode="scrollable"
|
1 2 3 4 5 6 7 8 9 10
| <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/tabLayout_id" android:layout_below="@+id/toolbar_id" android:background="@color/colorPrimary" app:tabMode="scrollable" app:tabGravity="fill" app:tabTextColor="@android:color/white" app:tabSelectedTextColor="@color/colorAccent"/>
|
接著創建十個layout
![](tabs10.png)
創建十個Java Class
![](tabs11.png)
在Activity裡添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); adapter.addFragment(new OneFragment(), "ITEM ONE"); adapter.addFragment(new TwoFragment(), "ITEM TWO"); adapter.addFragment(new ThreeFragment(), "ITEM THREE"); adapter.addFragment(new FourFragment(), "ITEM FOUR"); adapter.addFragment(new FiveFragment(), "ITEM FIVE"); adapter.addFragment(new SixFragment(), "ITEM SIX"); adapter.addFragment(new SevenFragment(), "ITEM SEVEN"); adapter.addFragment(new EightFragment(), "ITEM EIGHT"); adapter.addFragment(new NineFragment(), "ITEM NINE"); adapter.addFragment(new TenFragment(), "ITEM TEN"); viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
|
運行效果如下:
![](tabs18.gif)
Create a Tab Layout with Icon
接下來我們以Fixed Mode實現,在TabLayout頁籤裡,只顯示icon的效果
首先在XML裡,把app:tabMode設為**”fixed”**
1 2 3 4 5 6 7 8 9 10
| <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/tabLayout_id" android:layout_below="@+id/toolbar_id" android:background="@color/colorPrimary" app:tabMode="fixed" app:tabGravity="fill" app:tabTextColor="@android:color/white" app:tabSelectedTextColor="@color/colorAccent"/>
|
接著同樣新增3個Layout,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/recents" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:textSize="40sp" android:textStyle="bold"/> </RelativeLayout>
|
創建剛剛新增layout的java class(Fragment)
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class RecentsFragment extends Fragment {
View view;
public RecentsFragment() {} @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { view = inflater.inflate(R.layout.recents_layout,container,false); return view; } }
|
創建ViewPagerAdapter,這邊我們沒有覆寫**getPageTitle()**方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class ViewPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList = new ArrayList<>(); private List<String> fragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) { super(fm); }
@Override public Fragment getItem(int position) { return fragmentList.get(position); }
@Override public int getCount() { return fragmentList.size(); }
public void addFragment(Fragment fragment, String title) { fragmentList.add(fragment); fragmentTitleList.add(title); } }
|
在Activity裡初始化,在綁定Adapter後,使用getTabAt()取得各項Tab後,設定各個icon
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class MainActivity extends AppCompatActivity {
Toolbar toolbar; TabLayout tabLayout; ViewPager viewPager;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); toolbar = findViewById(R.id.toolbar_id); setSupportActionBar(toolbar);
viewPager = findViewById(R.id.viewPager_id); ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); adapter.addFragment(new RecentsFragment(),"RECENTS"); adapter.addFragment(new FavoritesFragment(),"FAVORITES"); adapter.addFragment(new NearbyFragment(),"NEARBY"); viewPager.setAdapter(adapter);
tabLayout = findViewById(R.id.tabLayout_id); tabLayout.setupWithViewPager(viewPager); tabLayout.getTabAt(0).setIcon(R.drawable.phone); tabLayout.getTabAt(1).setIcon(R.drawable.heart); tabLayout.getTabAt(2).setIcon(R.drawable.account); } }
|
運行效果如下:
![](tabs14.gif)
Create a Tab Layout with Icon and Text
如果想要Tabs同時擁有圖片和文字,只要在ViewPageAdapter裡,覆寫**getPageTitle()**方法就行了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class ViewPagerAdapter extends FragmentPagerAdapter {
private List<Fragment> fragmentList = new ArrayList<>(); private List<String> fragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm) { super(fm); }
@Override public Fragment getItem(int position) { return fragmentList.get(position); }
@Override public int getCount() { return fragmentList.size(); }
@Nullable @Override public CharSequence getPageTitle(int position) { return fragmentTitleList.get(position); }
public void addFragment(Fragment fragment, String title) { fragmentList.add(fragment); fragmentTitleList.add(title); } }
|
運行效果如下:
![](tabs15.gif)
Create a Tabs item with Java
不使用ViewPager,也可以透過代碼創建TabsItem
1 2 3 4 5
| tabLayout = findViewById(R.id.tabLayout_id);
tabLayout.addTab(tabLayout.newTab().setText("RECENTS").setIcon(R.drawable.phone)); tabLayout.addTab(tabLayout.newTab().setText("FAVORITES").setIcon(R.drawable.heart)); tabLayout.addTab(tabLayout.newTab().setText("NEARBY").setIcon(R.drawable.account));
|
Create a Tabs item in XML
不使用ViewPager,在Layout.xml裡,創建TabItem
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/tabLayout_id" android:layout_below="@+id/toolbar_id" android:background="@color/colorPrimary" app:tabMode="fixed" app:tabGravity="fill">
<android.support.design.widget.TabItem android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/recents" android:icon="@drawable/phone"/>
<android.support.design.widget.TabItem android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/favorites" android:icon="@drawable/heart"/>
<android.support.design.widget.TabItem android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/nearby" android:icon="@drawable/account"/>
</android.support.design.widget.TabLayout>
|
參考資料:
Android TabLayout
Material Design