1. ViewPager要點:
- ViewPager 是一個布局管理類(layout manager),用於提供頁面的左右滑動功能,類似於ListView,也有為ViewPager提供 資料(Fragment)的 adapter 控制類(FragmentPagerAdapter, FragmentStatePagerAdapter)。
- ViewPager 經常和 Fragment 一起使用,結合ActionBar 的 Tab,實現 tab 頁面的左右滑動。
- ViewPager 屬於 android sdk 擴充包,若要使用 ViewPager,需要外部匯入擴充包:android-support-v4.jar
2. 實現功能:本例實現的功能效果如所示:
實現 tab 頁的左右滑動的好處是,由於我們經常習慣單手操作手機,而單手切換 tab 頁是非常困難的,而 tab 頁面的左右滑動 功能正好可以解決這個問題,提供更加方便的互動。
3. 原理說明:整個應用可以分為的幾個模組:
- 主介面Activity 主要由一個 ViewPager 組成,裡面裝載了三個 Fragment 頁面,進行左右滑動;
- 主介面Activity 的ActionBar 中建立三個 Tab 按鍵(Tab Button);
- ActionBar 與 ViewPager 之間的互動關係如下:ViewPager 帶動其裝載的三個 Fragment 左右切換的同時,控制其相對應的Action Tab Button 的左右切換;反過來,當使用者手動切換三個 Tab Button 時,控制 ViewPager 中相對應的 Fragment 的切換。
4. 具體步驟:4.1 建立工程並匯入android-support-v4.jar擴充包:
- 建立一個名為ActionTabWithSlippingFragment。
- 匯入android-support-v4.jar擴充包:網上很多匯入方法都表示要通過 “Project - Properties - Java Build Path - Add External JARs” 進行匯入,這樣可以保證編譯通過,但是啟動並執行時候會出錯!這裡我用的匯入方法如下:
- 首先在工程目錄下建立一個檔案夾 libs,然後從 "android sdk目錄\extras\android\compatibility\v4" 下將 android-support-v4.jar 手動拷貝到建立的 libs 目錄下,最後右擊工程選擇 “Refresh” 重新整理即可,這時可以看到 libs 目錄和 Android Dependencies 目錄下均有 android-support-v4.jar 出現,這就表示匯入成功了!如所示:
4.2 建立三個 Fragment 類作為可滑動的 Tab 頁(view),並由 ViewPager來管理(manager):
- 建立三個 Fragement 類:Fragment1.java,Fragment2.java,Fragment3.java,同時為其各自建立布局視圖檔案:fragment1.xml,fragment2.xml,fragment3.xml,分別設定紅(R)、綠(G)、藍(B)背景。
- Fragment1.java建立如下,關鍵實現其 onCreateView 方法,設定其布局:
public class Fragment1 extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {return inflateAndSetupView(inflater, container, savedInstanceState, R.layout.fragment1);}private View inflateAndSetupView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState, int layoutResourceId) {View layout = inflater.inflate(layoutResourceId, container, false);return layout;} }
- fragment1.xml 主要定義一個帶有紅色背景的的LinearLayout:
<?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" android:background="#FF0000" > <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:gravity="center" android:text="@string/frag_1" android:textSize="30dp" android:textStyle="bold" android:textColor="#FFFFFF" /></LinearLayout>
4.3 建立主介面 Activity:ActionTabWithSlippingFragmentActivity,及其對應的布局檔案:main.xml:
- 設定 ActionBar 的樣式,如:無回退按鍵、無標題等——setUpActionBar()
- 初始化並設定 ViewPager,兩個要點:首先要定義並設定 ViewPager 所需要的資料控制類 ViewPagerAdapter,ViewPagerAdapter 必須實現如何返回對應位置的 Fragment、頁數、網頁標題;其次,要實現 ViewPager 的翻頁監聽介面(OnPageChangeListener),主要是實現當前頁面被切換時需要導航到對應位置的action tab button,必要的時候,還需要實現在頁面翻動的各個狀態下(正在翻動、翻動即將停止、翻動完全停止)的相應處理——setUpViewPager()
- 然後需要建立三個 tab button,並實現 tab 的監聽介面:主要是當選擇相應 tab 時,如何切換 ViewPager 的相應頁面——setUpTabs()
- ActionTabWithSlippingFragmentActivity.java 的實現部分
public class ActionTabWithSlippingFragmentActivity extends FragmentActivity implements ActionBar.TabListener{ private Fragment1 mFragment1 = new Fragment1();private Fragment2 mFragment2 = new Fragment2();private Fragment3 mFragment3 = new Fragment3();private static final int TAB_INDEX_COUNT = 3;private static final int TAB_INDEX_ONE = 0;private static final int TAB_INDEX_TWO = 1;private static final int TAB_INDEX_THREE = 2;private ViewPager mViewPager;private ViewPagerAdapter mViewPagerAdapter;/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); setUpActionBar(); setUpViewPager(); setUpTabs(); } private void setUpActionBar() { final ActionBar actionBar = getActionBar(); actionBar.setHomeButtonEnabled(false); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); actionBar.setDisplayShowTitleEnabled(false); actionBar.setDisplayShowHomeEnabled(false); } private void setUpViewPager() { mViewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager()); mViewPager = (ViewPager)findViewById(R.id.pager); mViewPager.setAdapter(mViewPagerAdapter); mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override public void onPageSelected(int position) { final ActionBar actionBar = getActionBar(); actionBar.setSelectedNavigationItem(position); } @Override public void onPageScrollStateChanged(int state) { switch(state) { case ViewPager.SCROLL_STATE_IDLE: //TODO break; case ViewPager.SCROLL_STATE_DRAGGING: //TODO break; case ViewPager.SCROLL_STATE_SETTLING: //TODO break; default: //TODO break; } } }); } private void setUpTabs() { final ActionBar actionBar = getActionBar(); for (int i = 0; i < mViewPagerAdapter.getCount(); ++i) { actionBar.addTab(actionBar.newTab() .setText(mViewPagerAdapter.getPageTitle(i)) .setTabListener(this)); } } @Override protected void onDestroy() { super.onDestroy(); } public class ViewPagerAdapter extends FragmentPagerAdapter {public ViewPagerAdapter(FragmentManager fm) {super(fm);// TODO Auto-generated constructor stub}@Overridepublic Fragment getItem(int position) {// TODO Auto-generated method stubswitch (position) {case TAB_INDEX_ONE:return mFragment1;case TAB_INDEX_TWO:return mFragment2;case TAB_INDEX_THREE:return mFragment3;}throw new IllegalStateException("No fragment at position " + position);}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn TAB_INDEX_COUNT;} @Overridepublic CharSequence getPageTitle(int position) {String tabLabel = null;switch (position) {case TAB_INDEX_ONE:tabLabel = getString(R.string.tab_1);break;case TAB_INDEX_TWO:tabLabel = getString(R.string.tab_2);break;case TAB_INDEX_THREE:tabLabel = getString(R.string.tab_3);break;}return tabLabel;} }@Overridepublic void onTabReselected(Tab tab, FragmentTransaction ft) {// TODO Auto-generated method stub}@Overridepublic void onTabSelected(Tab tab, FragmentTransaction ft) {// TODO Auto-generated method stubmViewPager.setCurrentItem(tab.getPosition());}@Overridepublic void onTabUnselected(Tab tab, FragmentTransaction ft) {// TODO Auto-generated method stub}}
- main.xml 的實現部分:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" > </android.support.v4.view.ViewPager></RelativeLayout>
4.4 結束語:
- 關於 ViewPager 結合ActionBar 和 Fragment 實現頁面滑動式 tab 功能在 google 的官方開發文檔中也有說明,本例相關原理亦以此作為參考,詳情請查閱:http://developer.android.com/reference/android/support/v4/view/ViewPager.html
- 原始碼供開放,無需積分:http://download.csdn.net/detail/ixiaobu/4743378