android 使用Fragment實現ViewPager滑動

博主描述簡單明瞭,非常感謝,博主鏈接參考:http://blog.csdn.net/harvic880925/article/details/38660861

本篇效果圖:

在第一個頁面加一個Btn                                          第一頁面向第二頁面滑動

  

         第二頁面向第三個頁面滑動


一、概述

從前面幾篇文章,我們知道,實現ViewPager是要有適配器的,我們前面用的適配器是PagerAdapter,而對於fragment,它所使用的適配器是:FragmentPagerAdapter.先看看官方對於這個類的解釋:(英文下面有中文解釋)

原文:

Class Overview


Implementation of PagerAdapter that represents each page as a Fragment that is persistently kept in the fragment manager as long as the user can return to the page.

This version of the pager is best for use when there are a handful of typically more static fragments to be paged through, such as a set of tabs. The fragment of each page the user visits will be kept in memory, though its view hierarchy may be destroyed when not visible. This can result in using a significant amount of memory since fragment instances can hold on to an arbitrary amount of state. For larger sets of pages, consider FragmentStatePagerAdapter.

When using FragmentPagerAdapter the host ViewPager must have a valid ID set.

Subclasses only need to implement getItem(int) and getCount() to have a working adapter.

譯文:(譯的不好,大家可在評論中補充)

FragmentPagerAdapter派生自PagerAdapter,它是用來呈現Fragment頁面的,這些Fragment頁面會一直保存在fragment manager中,以便用戶可以隨時取用。

這個適配器最好用於有限個靜態fragment頁面的管理。儘管不可見的視圖有時會被銷燬,但用戶所有訪問過的fragment都會被保存在內存中。因此fragment實例會保存大量的各種狀態,這就造成了很大的內存開銷。所以如果要處理大量的頁面切換,建議使用FragmentStatePagerAdapter.

每一個使用FragmentPagerAdapter的ViewPager都要有一個有效的ID集。(沒理解什麼意思)

對於FragmentPagerAdapter的派生類,只需要重寫getItem(int)和getCount()就可以了。

二、具體實現


1、適配器實現——FragmentPagerAdapter

先看完整代碼,再細講:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public class FragAdapter extends FragmentPagerAdapter {  
  2.   
  3.     private List<Fragment> mFragments;  
  4.       
  5.     public FragAdapter(FragmentManager fm,List<Fragment> fragments) {  
  6.         super(fm);  
  7.         // TODO Auto-generated constructor stub  
  8.         mFragments=fragments;  
  9.     }  
  10.   
  11.     @Override  
  12.     public Fragment getItem(int arg0) {  
  13.         // TODO Auto-generated method stub  
  14.         return mFragments.get(arg0);  
  15.     }  
  16.   
  17.     @Override  
  18.     public int getCount() {  
  19.         // TODO Auto-generated method stub  
  20.         return mFragments.size();  
  21.     }  
  22.   
  23. }  
這裏有三個函數,根據第一部分的官方文檔,可知,對於FragmentPagerAdapter的派生類,只重寫getItem(int)和getCount()就可以了。

對於構造函數,這裏申請了一個Fragment的List對象,用於保存用於滑動的Fragment對象,並在創造函數中初始化:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public FragAdapter(FragmentManager fm,List<Fragment> fragments) {  
  2.     super(fm);  
  3.     // TODO Auto-generated constructor stub  
  4.     mFragments=fragments;  
  5. }  
然後在getItem(int arg0)中,根據傳來的參數arg0,來返回當前要顯示的fragment,下面是getItem的官方解釋,難度不大,不再細講。

public abstract Fragment getItem (int position)

Return the Fragment associated with a specified position.

最後,getCount()返回用於滑動的fragment總數;

從構造函數所以看出,我們要構造Fragment的集合纔行,所以下面我們就先產生我們所需要的Fragment類;

2、三個Fragment類

第一個Fragment類:

XML:(layout1.xml)

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="#ffffff"  
  6.     android:orientation="vertical" >  
  7.       
  8.     <Button android:id="@+id/fragment1_btn"  
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="show toast"  
  12.         />  
  13. </LinearLayout>  
在其中加入了一個Btn

Java代碼:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public class Fragment1 extends Fragment {  
  2.       
  3.     @Override  
  4.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  5.             Bundle savedInstanceState) {  
  6.         // TODO Auto-generated method stub  
  7.         View view= inflater.inflate(R.layout.layout1, container, false);  
  8.           
  9.         //對View中控件的操作方法  
  10.         Button btn = (Button)view.findViewById(R.id.fragment1_btn);  
  11.         btn.setOnClickListener(new View.OnClickListener() {  
  12.               
  13.             @Override  
  14.             public void onClick(View v) {  
  15.                 // TODO Auto-generated method stub  
  16.                 Toast.makeText(getActivity(), "點擊了第一個fragment的BTN", Toast.LENGTH_SHORT).show();  
  17.             }  
  18.         });  
  19.         return view;  
  20.     }  
  21. }  
在onCreateView()中返回要顯示的View,上面這段代碼簡單演示瞭如何對視圖裏的控件進行操作,難度不大,不再細講,如果對Fragment不太熟悉的同學,先看看這篇文章:《Android Fragment完全解析,關於碎片你所需知道的一切》

第二個Fragment類:

XML代碼:(layout2.xml)原生代碼,沒有做任何更改

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="#ffff00"  
  6.     android:orientation="vertical" >  
  7.       
  8.   
  9. </LinearLayout>  
java代碼:
[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public class Fragment2 extends Fragment {  
  2.       
  3.     @Override  
  4.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  5.             Bundle savedInstanceState) {  
  6.         // TODO Auto-generated method stub  
  7.         View view=inflater.inflate(R.layout.layout2, container, false);  
  8.         return view;  
  9.     }  
  10.   
  11. }  

第三個Fragment類:

XML代碼:(layout3.xml)同樣,原生代碼,沒做任何更改

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="#ff00ff"  
  6.     android:orientation="vertical" >  
  7.       
  8.   
  9. </LinearLayout>  
java代碼:
[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public class Fragment3 extends Fragment {  
  2.       
  3.     @Override  
  4.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  5.             Bundle savedInstanceState) {  
  6.         // TODO Auto-generated method stub  
  7.         View view=inflater.inflate(R.layout.layout3, container, false);  
  8.         return view;  
  9.     }  
  10.   
  11. }  

3、主activity實現

核心代碼:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public class MainActivity extends FragmentActivity {  
  2.   
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.         super.onCreate(savedInstanceState);  
  6.         setContentView(R.layout.activity_main);  
  7.   
  8.         //構造適配器  
  9.         List<Fragment> fragments=new ArrayList<Fragment>();  
  10.         fragments.add(new Fragment1());  
  11.         fragments.add(new Fragment2());  
  12.         fragments.add(new Fragment3());   
  13.         FragAdapter adapter = new FragAdapter(getSupportFragmentManager(), fragments);  
  14.           
  15.         //設定適配器  
  16.         ViewPager vp = (ViewPager)findViewById(R.id.viewpager);  
  17.         vp.setAdapter(adapter);  
  18.     }  
  19.   
  20. }  

首先有一個最值得注意的地方:Activity派生自FragmentActivity,其實這是有關Fragment的基礎知識,只有FragmentActivity才能內嵌fragment頁面,普通Activity是不行的。

這段代碼主要分爲兩步,第一步:構造適配器;第二步:設定適配器。

先看構造適配器的過程:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. //構造適配器  
  2. List<Fragment> fragments=new ArrayList<Fragment>();  
  3. fragments.add(new Fragment1());  
  4. fragments.add(new Fragment2());  
  5. fragments.add(new Fragment3());   
  6. FragAdapter adapter = new FragAdapter(getSupportFragmentManager(), fragments);  
構造一個fragment列表,然後將上面的三個Fragment類對應的實例添加進去,最後生成FragAdapter實例。
至於第二步,設定適配器,沒什麼好講的。

4、可能出現的問題

問題:在MainActivity中,當寫到這句:fragments.add(new Fragment1()); 向Fragment列表中添加Fragement對象實例時,會提示“無法將Fragment1()轉換爲fragment”

解決辦法 :這是因爲導入包不一致,一般的問題在於:在Fragment1中導入的是android.app.Fragment, 而在這裏導入類確是:android.support.v4.app.Fragment,包不同當然無法轉換,統一導入爲android.support.v4.app.Fragment之後就正常了.參考文章《android之cannot convert from Fragment1 to Fragment》



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

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


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