博主描述簡單明瞭,非常感謝,博主鏈接參考: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
先看完整代碼,再細講:
- public class FragAdapter extends FragmentPagerAdapter {
- private List<Fragment> mFragments;
- public FragAdapter(FragmentManager fm,List<Fragment> fragments) {
- super(fm);
- // TODO Auto-generated constructor stub
- mFragments=fragments;
- }
- @Override
- public Fragment getItem(int arg0) {
- // TODO Auto-generated method stub
- return mFragments.get(arg0);
- }
- @Override
- public int getCount() {
- // TODO Auto-generated method stub
- return mFragments.size();
- }
- }
對於構造函數,這裏申請了一個Fragment的List對象,用於保存用於滑動的Fragment對象,並在創造函數中初始化:
- public FragAdapter(FragmentManager fm,List<Fragment> fragments) {
- super(fm);
- // TODO Auto-generated constructor stub
- mFragments=fragments;
- }
public abstract Fragment getItem (int position)
Return the Fragment associated with a specified position.
從構造函數所以看出,我們要構造Fragment的集合纔行,所以下面我們就先產生我們所需要的Fragment類;
2、三個Fragment類
第一個Fragment類:
XML:(layout1.xml)
- <?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:background="#ffffff"
- android:orientation="vertical" >
- <Button android:id="@+id/fragment1_btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="show toast"
- />
- </LinearLayout>
Java代碼:
- public class Fragment1 extends Fragment {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- View view= inflater.inflate(R.layout.layout1, container, false);
- //對View中控件的操作方法
- Button btn = (Button)view.findViewById(R.id.fragment1_btn);
- btn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- Toast.makeText(getActivity(), "點擊了第一個fragment的BTN", Toast.LENGTH_SHORT).show();
- }
- });
- return view;
- }
- }
第二個Fragment類:
XML代碼:(layout2.xml)原生代碼,沒有做任何更改
- <?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:background="#ffff00"
- android:orientation="vertical" >
- </LinearLayout>
- public class Fragment2 extends Fragment {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- View view=inflater.inflate(R.layout.layout2, container, false);
- return view;
- }
- }
第三個Fragment類:
XML代碼:(layout3.xml)同樣,原生代碼,沒做任何更改
- <?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:background="#ff00ff"
- android:orientation="vertical" >
- </LinearLayout>
- public class Fragment3 extends Fragment {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- View view=inflater.inflate(R.layout.layout3, container, false);
- return view;
- }
- }
3、主activity實現
核心代碼:
- public class MainActivity extends FragmentActivity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //構造適配器
- List<Fragment> fragments=new ArrayList<Fragment>();
- fragments.add(new Fragment1());
- fragments.add(new Fragment2());
- fragments.add(new Fragment3());
- FragAdapter adapter = new FragAdapter(getSupportFragmentManager(), fragments);
- //設定適配器
- ViewPager vp = (ViewPager)findViewById(R.id.viewpager);
- vp.setAdapter(adapter);
- }
- }
首先有一個最值得注意的地方:Activity派生自FragmentActivity,其實這是有關Fragment的基礎知識,只有FragmentActivity才能內嵌fragment頁面,普通Activity是不行的。
這段代碼主要分爲兩步,第一步:構造適配器;第二步:設定適配器。先看構造適配器的過程:
- //構造適配器
- List<Fragment> fragments=new ArrayList<Fragment>();
- fragments.add(new Fragment1());
- fragments.add(new Fragment2());
- fragments.add(new Fragment3());
- FragAdapter adapter = new FragAdapter(getSupportFragmentManager(), fragments);
至於第二步,設定適配器,沒什麼好講的。
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 不勝感激!