ViewPager 詳解(三)---PagerTabStrip與PagerTitleStrip添加標題欄的異同

前言:在前兩篇文章中,我們講解了滑動頁面的的實現方法與四大函數的意義,但有時,僅僅實現頁面滑動是不夠的,還要有標題欄纔會顯得更友好。所以在這篇文章中,我將會向大家展示在android.support.v4包中的兩個控件PagerTabStrip與PagerTitleStrip,他們都是用來實現標題欄的,但各自有些不同,在這篇文章中,我們就講講它們各自都能實現怎樣的功能,又有哪些異同點。


相關文章:

1、《ViewPager 詳解(一)---基本入門》

2、《ViewPager 詳解(二)---詳解四大函數》

3、《ViewPager 詳解(三)---PagerTabStrip與PagerTitleStrip添加標題欄的異同》

4、《ViewPager 詳解(四)----自主實現滑動指示條》

5、《ViewPager 詳解(五)-----使用Fragment實現ViewPager滑動》


一、PagerTitleStrip

先看個簡單的,先上個效果圖,吸引大家一下眼球。

三個頁面間的滑動,此時是帶着上面的標題一塊滑動的。

  

看一下android 對於PagerTabStrip的官方解釋:

Class Overview


PagerTitleStrip is a non-interactive indicator of the current, next, and previous pages of a ViewPager. It is intended to be used as a child view of a ViewPager widget in your XML layout. Add it as a child of a ViewPager in your layout file and set its android:layout_gravity to TOP or BOTTOM to pin it to the top or bottom of the ViewPager. The title from each page is supplied by the methodgetPageTitle(int) in the adapter supplied to the ViewPager.

For an interactive indicator, see PagerTabStrip.

翻譯:

PagerTabStrip是ViewPager的一個關於當前頁面、上一個頁面和下一個頁面的一個非交互的指示器。它經常作爲ViewPager控件的一個子控件被被添加在XML佈局文件中。在你的佈局文件中,將它作爲子控件添加在ViewPager中。而且要將它的 android:layout_gravity 屬性設置爲TOP或BOTTOM來將它顯示在ViewPager的頂部或底部。每個頁面的標題是通過適配器的getPageTitle(int)函數提供給ViewPager的。


我可能譯的不大通順,這裏英文也難度不大,大家應該也能看得懂,但我還是着重講兩點:

1、首先,文中提到:在你的佈局文件中,將它作爲子控件添加在ViewPager中。

2、第二,標題的獲取,是重寫適配器的getPageTitle(int)函數來獲取的。


根據這兩點,我們就可以看代碼了:

1、XML佈局文件:

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     tools:context="com.example.testviewpage_2.MainActivity" >  
  6.   
  7.     <android.support.v4.view.ViewPager  
  8.         android:id="@+id/viewpager"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="200dip"  
  11.         android:layout_gravity="center">  
  12.           
  13.         <android.support.v4.view.PagerTitleStrip  
  14.             android:id="@+id/pagertitle"    
  15.             android:layout_width="wrap_content"    
  16.             android:layout_height="wrap_content"    
  17.             android:layout_gravity="top"  
  18.             />  
  19.           
  20.     </android.support.v4.view.ViewPager>  
  21.   
  22. </RelativeLayout>  
清楚的看到我們將.PagerTitleStrip將其作爲ViewPager的子控件直接嵌入其中;這是第一步;當然android:layout_gravity=""的值要設置爲top或bottom。將標題欄顯示在頂部或底部。

2、重寫適配器的getPageTitle()函數

便於大家有個整體認識,先貼全局代碼,然後再逐個講,這段代碼是在《ViewPager 詳解(二)---詳解四大函數》 直接更改來的,如果不太明白,先看看這篇文章。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.example.testviewpage_2;  
  2. /** 
  3.  * @author  harvic 
  4.  * @date 2014.8.12 
  5.  */  
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8. import android.app.Activity;  
  9. import android.os.Bundle;  
  10. import android.support.v4.view.PagerAdapter;  
  11. import android.support.v4.view.PagerTitleStrip;  
  12. import android.support.v4.view.ViewPager;  
  13. import android.view.LayoutInflater;  
  14. import android.view.View;  
  15. import android.view.ViewGroup;  
  16.   
  17. public class MainActivity extends Activity {  
  18.   
  19.     private View view1, view2, view3;  
  20.     private List<View> viewList;// view數組  
  21.     private ViewPager viewPager; // 對應的viewPager  
  22.       
  23.     private List<String> titleList;  //標題列表數組  
  24.       
  25.     @Override  
  26.     protected void onCreate(Bundle savedInstanceState) {  
  27.         super.onCreate(savedInstanceState);  
  28.         setContentView(R.layout.activity_main);  
  29.         viewPager = (ViewPager) findViewById(R.id.viewpager);  
  30.         LayoutInflater inflater = getLayoutInflater();  
  31.         view1 = inflater.inflate(R.layout.layout1, null);  
  32.         view2 = inflater.inflate(R.layout.layout2, null);  
  33.         view3 = inflater.inflate(R.layout.layout3, null);  
  34.   
  35.         viewList = new ArrayList<View>();// 將要分頁顯示的View裝入數組中  
  36.         viewList.add(view1);  
  37.         viewList.add(view2);  
  38.         viewList.add(view3);  
  39.           
  40.         titleList = new ArrayList<String>();// 每個頁面的Title數據  
  41.         titleList.add("王鵬");  
  42.         titleList.add("姜語");  
  43.         titleList.add("結婚");  
  44.   
  45.         PagerAdapter pagerAdapter = new PagerAdapter() {  
  46.   
  47.             @Override  
  48.             public boolean isViewFromObject(View arg0, Object arg1) {  
  49.                 // TODO Auto-generated method stub  
  50.                 //根據傳來的key,找到view,判斷與傳來的參數View arg0是不是同一個視圖  
  51.                 return arg0 == viewList.get((int)Integer.parseInt(arg1.toString()));  
  52.             }  
  53.   
  54.             @Override  
  55.             public int getCount() {  
  56.                 // TODO Auto-generated method stub  
  57.                 return viewList.size();  
  58.             }  
  59.   
  60.             @Override  
  61.             public void destroyItem(ViewGroup container, int position,  
  62.                     Object object) {  
  63.                 // TODO Auto-generated method stub  
  64.                 container.removeView(viewList.get(position));  
  65.             }  
  66.   
  67.             @Override  
  68.             public Object instantiateItem(ViewGroup container, int position) {  
  69.                 // TODO Auto-generated method stub  
  70.                 container.addView(viewList.get(position));  
  71.                   
  72.                 //把當前新增視圖的位置(position)作爲Key傳過去  
  73.                 return position;  
  74.             }  
  75.               
  76.             @Override  
  77.             public CharSequence getPageTitle(int position) {  
  78.                 // TODO Auto-generated method stub  
  79.                 return titleList.get(position);  
  80.             }  
  81.         };  
  82.   
  83.         viewPager.setAdapter(pagerAdapter);  
  84.   
  85.     }  
  86.   
  87. }  
相比較《ViewPager 詳解(二)---詳解四大函數》這裏作了一點更改:

1、變量

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. private List<String> titleList;  //標題列表數組  
申請了一個String數組,用來存儲三個頁面所對應的標題的

2、初始化

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. titleList = new ArrayList<String>();// 每個頁面的Title數據  
  2. titleList.add("王鵬");  
  3. titleList.add("姜語");  
  4. titleList.add("結婚");  
在初始化階段增加了這麼一段初始化數組的代碼。

3、重寫CharSequence getPageTitle(int )函數

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. @Override  
  2. public CharSequence getPageTitle(int position) {  
  3.     // TODO Auto-generated method stub  
  4.     return titleList.get(position);  
  5. }  
根據位置返回當前所對應的標題。


大家可以看到,其實這裏僅僅只重寫了getPageTitle()函數,將其根據不同的位置返回不同的字符串就可以實現上面的標題欄功能。第一和第二步有關數組和初始化,其實都是這了這一步,其實我們完全可以用下面這個代碼來取代它們:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. @Override  
  2. public CharSequence getPageTitle(int position) {  
  3.     // TODO Auto-generated method stub  
  4.     switch (position) {  
  5.     case 0:  
  6.         return "王鵬";  
  7.     case 1:  
  8.         return "姜語";  
  9.     case 2:  
  10.         return "結婚";  
  11.   
  12.     default:  
  13.         return "";  
  14.     }  
  15. }  
這樣效果是一樣一樣的,只是代碼不好維護而已。好了,有關PagerTabStrip的問題,我們就先說到這。

二、PagerTabStrip

同樣,先看個PagerTabStrip做出來的效果是怎樣的。

此例是以《ViewPager 詳解(一)---基本入門》爲基礎,更改而成;

    

可能看不出太大區別,其實這兩個實現的效果基本差不多,但有兩點不同:

1、PagerTabStrip在當前頁面下,會有一個下劃線條來提示當前頁面的Tab是哪個。

2、PagerTabStrip的Tab是可以點擊的,當用戶點擊某一個Tab時,當前頁面就會跳轉到這個頁面,而PagerTitleStrip則沒這個功能。


同樣,先看看官方對PagerTabStrip的解釋:

Class Overview


PagerTabStrip is an interactive indicator of the current, next, and previous pages of a ViewPager. It is intended to be used as a child view of a ViewPager widget in your XML layout. Add it as a child of a ViewPager in your layout file and set its android:layout_gravity to TOP or BOTTOM to pin it to the top or bottom of the ViewPager. The title from each page is supplied by the methodgetPageTitle(int) in the adapter supplied to the ViewPager.

For a non-interactive indicator, see PagerTitleStrip.

翻譯:

PagerTabStrip是ViewPager的一個關於當前頁面、上一個頁面和下一個頁面的一個可交互的指示器。它經常作爲ViewPager控件的一個子控件被被添加在XML佈局文件中。在你的佈局文件中,將它作爲子控件添加在ViewPager中。而且要將它的 android:layout_gravity 屬性設置爲TOP或BOTTOM來將它顯示在ViewPager的頂部或底部。每個頁面的標題是通過適配器的getPageTitle(int)函數提供給ViewPager的。

可以看到,除了第一句以外的其它句與PagerTitleStrip的解釋完全相同。即用法也是相同的。只是PagerTabStrip是可交互的,而PagerTitleStrip是不可交互的區別。對於區別在哪些位置,即是上面的兩點(是否可點擊與下劃線指示條)。


用法與PagerTitleStrip完全相同,即:

1、首先,文中提到:在你的佈局文件中,將它作爲子控件添加在ViewPager中。

2、第二,標題的獲取,是重寫適配器的getPageTitle(int)函數來獲取的。

看看實例:

1、XML佈局

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     tools:context="com.example.testviewpage_2.MainActivity" >  
  6.   
  7.     <android.support.v4.view.ViewPager  
  8.         android:id="@+id/viewpager"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:layout_gravity="center">  
  12.           
  13.                 <android.support.v4.view.PagerTabStrip  
  14.             android:id="@+id/pagertab"  
  15.             android:layout_width="match_parent"  
  16.             android:layout_height="wrap_content"   
  17.             android:layout_gravity="top"/>  
  18.           
  19.     </android.support.v4.view.ViewPager>  
  20.   
  21. </RelativeLayout>  
可以看到,同樣,是將PagerTabStrip作爲ViewPager的一個子控件直接插入其中,當然android:layout_gravity=""的值一樣要設置爲top或bottom。

2、重寫適配器的getPageTitle()函數

全部代碼:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package com.example.testviewpage_2;  
  2.   
  3. /** 
  4.  * @author  harvic 
  5.  * @date 2014.8.13 
  6.  */  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.   
  10. import android.app.Activity;  
  11. import android.os.Bundle;  
  12. import android.support.v4.view.PagerAdapter;  
  13. import android.support.v4.view.ViewPager;  
  14. import android.view.LayoutInflater;  
  15. import android.view.View;  
  16. import android.view.ViewGroup;  
  17.   
  18. public class MainActivity extends Activity {  
  19.   
  20.     private View view1, view2, view3;  
  21.     private List<View> viewList;// view數組  
  22.     private ViewPager viewPager; // 對應的viewPager  
  23.   
  24.     private List<String> titleList;  
  25.   
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.activity_main);  
  30.   
  31.         viewPager = (ViewPager) findViewById(R.id.viewpager);  
  32.         LayoutInflater inflater = getLayoutInflater();  
  33.         view1 = inflater.inflate(R.layout.layout1, null);  
  34.         view2 = inflater.inflate(R.layout.layout2, null);  
  35.         view3 = inflater.inflate(R.layout.layout3, null);  
  36.   
  37.         viewList = new ArrayList<View>();// 將要分頁顯示的View裝入數組中  
  38.         viewList.add(view1);  
  39.         viewList.add(view2);  
  40.         viewList.add(view3);  
  41.   
  42.         titleList = new ArrayList<String>();// 每個頁面的Title數據  
  43.         titleList.add("王鵬");  
  44.         titleList.add("姜語");  
  45.         titleList.add("結婚");  
  46.   
  47.         PagerAdapter pagerAdapter = new PagerAdapter() {  
  48.   
  49.             @Override  
  50.             public boolean isViewFromObject(View arg0, Object arg1) {  
  51.                 // TODO Auto-generated method stub  
  52.                 return arg0 == arg1;  
  53.             }  
  54.   
  55.             @Override  
  56.             public int getCount() {  
  57.                 // TODO Auto-generated method stub  
  58.                 return viewList.size();  
  59.             }  
  60.   
  61.             @Override  
  62.             public void destroyItem(ViewGroup container, int position,  
  63.                     Object object) {  
  64.                 // TODO Auto-generated method stub  
  65.                 container.removeView(viewList.get(position));  
  66.             }  
  67.   
  68.             @Override  
  69.             public Object instantiateItem(ViewGroup container, int position) {  
  70.                 // TODO Auto-generated method stub  
  71.                 container.addView(viewList.get(position));  
  72.   
  73.                 return viewList.get(position);  
  74.             }  
  75.   
  76.             @Override  
  77.             public CharSequence getPageTitle(int position) {  
  78.                   
  79.                 return titleList.get(position);  
  80.             }  
  81.         };  
  82.   
  83.         viewPager.setAdapter(pagerAdapter);  
  84.   
  85.     }  
  86.   
  87. }  
這裏的代碼與PagerTitleStrip的完全相同,就不再講解了。

就這樣,我們就講完了有關PagerTabStrip的簡單使用方法。下面講一講PagerTabStrip的擴展。

3、擴展:PagerTabStrip屬性更改

在源碼中,大家可以看到有個工程叫TestViewPage_PagerTabStrip_extension,運行一下,效果是這樣的:

    

在上面兩個圖中可以看到,我更改了兩個地方:

1、下劃線顏色,原生是黑色,我變成了綠色;

2、在Tab標題前加了一個圖片;

下面說說是如何更改的:

1、更改下劃線顏色:

主要靠PagerTabStrip的setTabIndicatorColorResource方法;

代碼如下:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. pagerTabStrip = (PagerTabStrip) findViewById(R.id.pagertab);  
  2. pagerTabStrip.setTabIndicatorColorResource(R.color.green);  

2、添加標題——重寫適配器CharSequence getPageTitle(int)方法

在CharSequence getPageTitle(int position)方法返回值是,我們不返回String對象,而採用SpannableStringBuilder來構造了下包含圖片的擴展String對像;

具體代碼如下,不再細講,大家可以看看SpannableStringBuilder的使用方法,就可理解了。

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. @Override  
  2. public CharSequence getPageTitle(int position) {  
  3.   
  4.     SpannableStringBuilder ssb = new SpannableStringBuilder("  "+titleList.get(position)); // space added before text  
  5.                                         // for  
  6.     Drawable myDrawable = getResources().getDrawable(  
  7.             R.drawable.ic_launcher);  
  8.     myDrawable.setBounds(00, myDrawable.getIntrinsicWidth(),  
  9.             myDrawable.getIntrinsicHeight());  
  10.     ImageSpan span = new ImageSpan(myDrawable,  
  11.             ImageSpan.ALIGN_BASELINE);  
  12.   
  13.     ForegroundColorSpan fcs = new ForegroundColorSpan(Color.GREEN);// 字體顏色設置爲綠色  
  14.     ssb.setSpan(span, 01, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);// 設置圖標  
  15.     ssb.setSpan(fcs, 1, ssb.length(),  
  16.             Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);// 設置字體顏色  
  17.     ssb.setSpan(new RelativeSizeSpan(1.2f), 1, ssb.length(),  
  18.             Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
  19.     return ssb;  
  20. }  

三、總結

通過前面的講解,我們應該清楚的認識到PagerTabStrip與PagerTitleStrip在添加標題欄的異同,但他們實現的標題欄效果很不好,不能指定一個頁面一次顯示一個,或者全部顯示,而且標題還滑動。所以註定主流的App都沒有用這個玩意的。所以這裏也只是一個過渡,在開發中,我們也不建議使用這兩個東東。


爲什麼無法改變PagerTabStrip的滑動特性,看這個貼子:《Fixed Tabs with android.support.v4.view.PagerTabStrip or ViewPagerIndicator》


參考文章:

《Android多屏滑動:ViewPager基礎使用及PagerTabStrip先天缺陷(附源碼)》

《android:修改PagerTabStrip中的背景顏色,標題字體的樣式、顏色和圖標以及指示條的顏色》


所有源碼打包在一起,分爲三個:

1、TestViewPage_pagerTitleStrip:pagerTitleStrip實現實例

2、TestViewPage_PagerTabStrip :PagerTabStrip實現實例

3、TestViewPage_PagerTabStrip_extension:PagerTabStrip的擴展實現


源碼下載地址:http://download.csdn.net/detail/harvic880925/7747417


請大家尊重原創者版權,轉載請標明出處:http://blog.csdn.net/harvic880925/article/details/38521865 謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章