Android開發之ViewPager+ActionBar+Fragment實現響應式可滑動Tab


 今天我們要實現的這個效果呢,在Android的應用中十分地常見,我們可以看到下面兩張圖,無論是系統內置的聯系人應用,還是AnyView的閱讀器應用,我們總能找到這樣的影子,當我們滑動屏幕時,Tab可以相應地完成切換,而當我們點擊Tab時,我們的屏幕同樣可以完成切換。講到滑動,我們會立即想到PagerView,講到ActionBar,我們立即會想到將ActionBar的導航模式。那么,我們今天要做的一件事情就是,通過這些組件的組合,來實現這樣一個效果。

 

     

     

       按照一般的思路,我們或許會這么做:首先,使用getActionBar()方法獲得操作欄,然后我們將操作欄的導航模式設置為Tab,並添加一些Tab,然后實現TabListener接口;其次,我們將多個布局通過Inflater()方法變成View,然后放到ViewPager里面(其實呢,ViewPager就是個容器啦,你換成FrameLayout也是一樣的,所以這里可以用Fragment替換就是這個道理),並實現OnPageChangeListener接口就可以了。由此我們可以寫出下面的代碼:

 

[java]  view plain copy
 
 
  1. package com.Android.AnyViewUI;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import android.os.Bundle;  
  6. import android.support.v4.app.FragmentActivity;  
  7. import android.support.v4.app.FragmentManager;  
  8. import android.support.v4.view.ViewPager;  
  9. import android.support.v4.view.ViewPager.OnPageChangeListener;  
  10. import android.app.ActionBar;  
  11. import android.app.ActionBar.Tab;  
  12. import android.app.ActionBar.TabListener;  
  13. import android.app.Activity;  
  14. import android.app.FragmentTransaction;  
  15. import android.view.LayoutInflater;  
  16. import android.view.View;  
  17.   
  18.   
  19. public class MainActivity extends FragmentActivity implements TabListener,OnPageChangeListener {  
  20.       
  21.     private ActionBar mActionBar;  
  22.     private ViewPager mViewPager;  
  23.     private TabPagerAdapter mAdapter;  
  24.     private ArrayList<View> mViews;  
  25.     private ArrayList<ActionBar.Tab> mTabs;  
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         setContentView(R.layout.layout_main);  
  30.         //取得ActionBar  
  31.         mActionBar=getActionBar();  
  32.         //以Tab方式導航  
  33.         mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);  
  34.         //禁用ActionBar標題  
  35.         mActionBar.setDisplayShowTitleEnabled(false);  
  36.         //禁用ActionBar圖標  
  37.         mActionBar.setDisplayUseLogoEnabled(false);  
  38.         //禁用ActionBar返回鍵  
  39.         mActionBar.setDisplayShowHomeEnabled(false);  
  40.         //添加Tabs  
  41.         mTabs=new ArrayList<ActionBar.Tab>();  
  42.           
  43.         ActionBar.Tab tab0=mActionBar.newTab();  
  44.         tab0.setText("界面一");  
  45.         tab0.setTabListener(this);  
  46.         mTabs.add(tab0);  
  47.         mActionBar.addTab(tab0);  
  48.           
  49.         ActionBar.Tab tab1=mActionBar.newTab();  
  50.         tab1.setText("界面二");  
  51.         tab1.setTabListener(this);  
  52.         mTabs.add(tab1);  
  53.         mActionBar.addTab(tab1);  
  54.           
  55.         ActionBar.Tab tab2=mActionBar.newTab();  
  56.         tab2.setText("界面三");  
  57.         tab2.setTabListener(this);  
  58.         mTabs.add(tab2);  
  59.         mActionBar.addTab(tab2);  
  60.           
  61.         //獲取ViewPager  
  62.         mViewPager=(ViewPager)findViewById(R.id.ViewPager);  
  63.         //初始化mViews  
  64.         mViews=new ArrayList<View>();  
  65.         mViews.add(LayoutInflater.from(this).inflate(R.layout.layout_0, null));  
  66.         mViews.add(LayoutInflater.from(this).inflate(R.layout.layout_1, null));  
  67.         mViews.add(LayoutInflater.from(this).inflate(R.layout.layout_2, null));  
  68.         //初始化mAdapter  
  69.         mAdapter=new TabPagerAdapter(mViews);  
  70.         mViewPager.setAdapter(mAdapter);  
  71.         mViewPager.setOnPageChangeListener(this);  
  72.         //默認顯示第二項  
  73.         mViewPager.setCurrentItem(2);  
  74.           
  75.     }  
  76.       
  77.   
  78.   
  79.     @Override  
  80.     public void onTabReselected(Tab mTab, FragmentTransaction arg1)   
  81.     {  
  82.           
  83.     }  
  84.   
  85.     @Override  
  86.     public void onTabSelected(Tab mTab, FragmentTransaction arg1)   
  87.     {  
  88.         if(mViewPager!=null)  
  89.         {  
  90.            mViewPager.setCurrentItem(mTab.getPosition());  
  91.         }  
  92.     }  
  93.   
  94.     @Override  
  95.     public void onTabUnselected(Tab mTab, FragmentTransaction arg1)   
  96.     {  
  97.           
  98.     }  
  99.   
  100.   
  101.     @Override  
  102.     public void onPageScrollStateChanged(int arg0)   
  103.     {  
  104.           
  105.     }  
  106.   
  107.   
  108.     @Override  
  109.     public void onPageScrolled(int arg0, float arg1, int arg2)   
  110.     {  
  111.           
  112.     }  
  113.   
  114.   
  115.     @Override  
  116.     public void onPageSelected(int Index)   
  117.     {  
  118.         //設置當前要顯示的View  
  119.         mViewPager.setCurrentItem(Index);  
  120.         //選中對應的Tab  
  121.         mActionBar.selectTab(mTabs.get(Index));  
  122.     }  
  123.   
  124. }  
        其中,TabPagerAdapter是一個繼承自PagerAdapter的適配器類:

 

 

[java]  view plain copy
 
 
  1. package com.Android.AnyViewUI;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import android.support.v4.view.PagerAdapter;  
  6. import android.support.v4.view.ViewPager;  
  7. import android.view.View;  
  8.   
  9. public class TabPagerAdapter extends PagerAdapter   
  10. {  
  11.   
  12.   
  13.   
  14.     private ArrayList<View> mViews;  
  15.     public TabPagerAdapter(ArrayList<View> mViews)  
  16.     {  
  17.         this.mViews=mViews;  
  18.     }  
  19.       
  20.     @Override  
  21.     public void destroyItem(View container, int position, Object object)   
  22.     {  
  23.         ((ViewPager)container).removeView(mViews.get(position));  
  24.     }  
  25.       
  26.     @Override  
  27.     public Object instantiateItem(View container, int position)   
  28.     {  
  29.         ((ViewPager)container).addView(mViews.get(position), 0);  
  30.          return mViews.get(position);  
  31.     }  
  32.       
  33.     @Override  
  34.     public int getCount()   
  35.     {  
  36.         return mViews.size();  
  37.     }  
  38.   
  39.     @Override  
  40.     public boolean isViewFromObject(View mView, Object mObject)   
  41.     {  
  42.         return (mView==mObject);  
  43.     }  
  44.   
  45.       
  46.   
  47. }  

           我們的代碼從邏輯上來講是沒有什么問題的,但是當我們試圖運行這段代碼的時候,我們發現這段代碼出了問題,而問題就出在OnTabSelected()上。但是我們冷靜下來想了想,沒有錯啊,那么問題到底出在哪里呢?看到網上的朋友說,這里這個適配器應該繼承自FragmentPagerAdapter:

 

 

[java]  view plain copy
 
 
  1. package com.Android.AnyViewUI;  
  2.   
  3. import android.support.v4.app.Fragment;  
  4. import android.support.v4.app.FragmentManager;  
  5. import android.support.v4.app.FragmentPagerAdapter;  
  6.   
  7. public class ViewPagerAdapter extends FragmentPagerAdapter {  
  8.   
  9.     //定義三個Fragment的索引  
  10.     public static final int Fragment_Index_0=0;  
  11.     public static final int Fragment_Index_1=1;  
  12.     public static final int Fragment_Index_2=2;  
  13.       
  14.     public ViewPagerAdapter(FragmentManager fragmentManager)   
  15.     {  
  16.         super(fragmentManager);  
  17.     }  
  18.   
  19.     @Override  
  20.     public Fragment getItem(int Index)   
  21.     {  
  22.         Fragment mFragemnt=null;  
  23.         switch(Index)  
  24.         {  
  25.           case Fragment_Index_0:  
  26.               mFragemnt=new Fragment_0();  
  27.               break;  
  28.           case Fragment_Index_1:  
  29.               mFragemnt=new Fragment_1();  
  30.               break;  
  31.           case Fragment_Index_2:  
  32.               mFragemnt=new Fragment_2();  
  33.               break;  
  34.         }  
  35.         return mFragemnt;  
  36.     }  
  37.   
  38.     @Override  
  39.     public int getCount()   
  40.     {  
  41.         return 3;  
  42.     }  
  43.   
  44. }  
      

 

        其中,Fragment_0、Fragment_1、Fragment_2是繼承自Fragment的類,由於三個布局基本一樣,這里只給出Fragment_0的代碼:

 

[java]  view plain copy
 
 
  1. package com.Android.AnyViewUI;  
  2.   
  3.   
  4. import android.os.Bundle;  
  5. import android.support.v4.app.Fragment;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9.   
  10. public class Fragment_0 extends Fragment   
  11. {  
  12.   
  13.     public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)   
  14.     {  
  15.         View mView=inflater.inflate(R.layout.layout_0, container, false);  
  16.         return mView;  
  17.     }  
  18.       
  19. }  

        現在,我們將開始寫好的代碼中的mAdapter用這個適配器類去替換,然后我們發現程序可以運行了,可是為什么啊?看了Android文檔,上面說FragmentPagerAdapter是實現了PagerAdapter,換句話說,真正起作用的還是PagerAdapter這個類,好,我們回頭看這個類,在我們開始的代碼中,我們在instantiateItem()、destroyItem()操作的對象始終是View,如果我們把這個View換成Fragment,把View[]換成Fragment[],在類內部使用FragmentManager對Fragment進行管理,我們會發現這樣的效果和繼承FragmentPagerAdapter是一樣的,這樣對於這兩個適配器的關系我們就已經很明確了。可是,我還是想知道為什么剛開始的那個方法不行呢?希望知道這個問題的答案的朋友,可以告訴我,最后放上效果圖:

 

 

ViewPager相關文章:

1、Android開發之ViewPager+ActionBar+Fragment實現響應式可滑動Tab

2、Android開發學習之基於ViewPager實現Gallery畫廊效果

3、Android開發學習之使用ViewPager+PagerTabStrip制作可滑動的Tab

4、Android開發學習之使用ViewPager打造應用引導界面面


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM