ViewPager 從入門到帶你擼個啓動頁之Fragment+ViewPager(二)

轉載請註明出處(萬分感謝!):
http://blog.csdn.net/javazejian/article/details/52141393

關聯文章:

ViewPager 從入門到帶你擼個啓動頁之ViewPager基礎入門(一)

ViewPager 從入門到帶你擼個啓動頁之Fragment+ViewPager(二)

ViewPager 從入門到帶你擼個啓動頁之實戰啓動頁(三)

ViewPager 從入門到帶你擼個啓動頁之實戰PageTransformer切換動畫特效(四)

  上一篇我們分享了ViewPager的基本用法後,相信大家對ViewPager的使用已經有比較清晰的認識了,這篇我們準備來使用官方推薦的Fragment+ViewPager組合來實現上一篇的效果。

Fragment+ViewPager的基本用法

1.FragmentPagerAdapter與FragmentStatePagerAdapter

  當ViewPager與Fragment結合使用時,我們所需要使用的數據適配器就已不再是PagerAdapter而是官方另外提供的FragmentPagerAdapter與FragmentStatePagerAdapter數據適配器,下面我們先來聊聊這兩個FragmentPagerAdapter與FragmentStatePagerAdapter的使用方法及其主要區別。

  • FragmentPagerAdapter

  FragmentPagerAdapter 繼承自 PagerAdapter。相比通用的 PagerAdapter,該類更專注於每一頁均爲 Fragment 的情況。該類內的每一個生成的 Fragment 都將保存在內存之中,儘管不可見的視圖有時會被銷燬,但用戶所有訪問過的fragment都會被保存在內存中,因此fragment實例會保存大量的各種狀態,這就造成了很大的內存開銷。所以FragmentPagerAdapter比較適用於那些相對靜態的頁,數量也比較少的應用情景,如主流主界面;如果需要處理有很多頁,並且數據動態性較大、佔用內存較多的情況,應該使用FragmentStatePagerAdapter。對應實現FragmentPagerAdapter ,我們只需重寫getCount()與getItem()兩個方法,因此相對於繼承自 PagerAdapter,更方便一些。接下來我們來看看如何用代碼實現FragmentPagerAdapter

 class MyFragmentAdapter extends FragmentPagerAdapter{

        List<Fragment> list;

        public MyFragmentAdapter(FragmentManager fm,List<Fragment> list) {
            super(fm);
            this.list=list;
        }

        /**
         * 返回需要展示的fragment
         * @param position
         * @return
         */
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        /**
         * 返回需要展示的fangment數量
         * @return
         */
        @Override
        public int getCount() {
            return list.size();
        }
}

代碼相當簡單,我們這裏簡單以下兩個函數

  • getItem(int position)

    這個函數實際上是根據下標position需要展示的fragment界面,該方法是在PagerAdapter#instantiateItem()方法中被調用的,大家只要看一下FragmentPagerAdapter源碼就清晰了。

  • getCount()
    這個函數就更簡單了,返回需要展示的fragment的總個數。

到此我們就對FragmentPagerAdapter介紹完了,下面我們接着看看FragmentStatePagerAdapter類。

  • FragmentStatePagerAdapter

  FragmentStatePagerAdapter 和 FragmentPagerAdapter 一樣,是繼承子 PagerAdapter。但是它們的不同點在於其類名中的 ‘State’ 所表明的含義一樣,該 PagerAdapter 的實現將只保留當前頁面,當頁面離開視線後,就會被消除,釋放其資源;而在頁面需要顯示時,再生成新的頁面。這樣實現的最大好處在於當擁有大量的頁面時,不必在內存中佔用大量的內存。我們在實現FragmentStatePagerAdapter是也同樣只需重寫getCount()與getItem()兩個方法,而且其方法含義跟FragmentPagerAdapter是一樣的。下面我們來看看實現案例,其實就改了個繼承類而已。

class MyFragmentStateAdapter extends FragmentStatePagerAdapter{

        List<Fragment> list;

        public MyFragmentStateAdapter(FragmentManager fm,List<Fragment> list) {
            super(fm);
            this.list=list;
        }

        /**
         * 返回需要展示的fragment
         * @param position
         * @return
         */
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        /**
         * 返回需要展示的fangment數量
         * @return
         */
        @Override
        public int getCount() {
            return list.size();
        }
    }

  從代碼的角度來看就換了繼承類,其他都沒有變化。最後我們來實現一個簡單例子;
我們先來編寫需要的Fragment佈局.fragment.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv"
        android:textSize="20dp"
        android:textColor="@color/white"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

FragmentView.java代碼如下:

package com.zejian.activity;

package com.zejian.viewpager;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
 * Created by zejian
 * Time 16/8/7.
 * Description:
 */
public class FragmentView extends Fragment {

    private Bundle arg;
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        arg=getArguments();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
       View view= inflater.inflate(R.layout.fragment,null);
        TextView tv= (TextView) view.findViewById(R.id.tv);
        int page=arg.getInt("pager_num");

        if (page==1){
            view.setBackgroundResource(R.color.colorAccent);
        }else if(page==2){
            view.setBackgroundResource(R.color.greed);
        }else if(page==3){
            view.setBackgroundResource(R.color.red);
        }else if(page==4){
            view.setBackgroundResource(R.color.colorPrimary);
        }

        tv.setText(arg.getString("Title"));
        return view;
    }


   public static FragmentView newInstance(Bundle args) {
        FragmentView fragment = new FragmentView();
        fragment.setArguments(args);
        return fragment;
    }

}

  Fragment的代碼也很清新,我們通過傳遞過來的參數去判斷每個fragment的背景顏色,並設置標題名稱,最後返回我們需要展示的view。我們再來看看actvity的佈局文件
activity_vp_fg.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v4.view.ViewPager>
</LinearLayout>

VP_FG_Activity.java

package com.zejian.viewpager;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by zejian
 * Time 16/8/7.
 * Description:
 */
public class VP_FG_Activity extends FragmentActivity {

    private ViewPager viewPager;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vp_fg);
        viewPager= (ViewPager) findViewById(R.id.vp);
        initData();
    }

    public void initData(){

        List<Fragment> list=new ArrayList<>();

        Bundle bundle1=new Bundle();
        bundle1.putString("Title","第一個Fragment");
        bundle1.putInt("pager_num",1);
        Fragment fg1=FragmentView.newInstance(bundle1);

        Bundle bundle2=new Bundle();
        bundle2.putString("Title","第二個Fragment");
        bundle2.putInt("pager_num",2);
        Fragment fg2=FragmentView.newInstance(bundle2);

        Bundle bundle3=new Bundle();
        bundle3.putString("Title","第三個Fragment");
        bundle3.putInt("pager_num",3);
        Fragment fg3=FragmentView.newInstance(bundle3);

        Bundle bundle4=new Bundle();
        bundle4.putString("Title","第四個Fragment");
        bundle4.putInt("pager_num",4);
        Fragment fg4=FragmentView.newInstance(bundle4);

        list.add(fg1);
        list.add(fg2);
        list.add(fg3);
        list.add(fg4);

        viewPager.setAdapter(new MyFragmentAdapter(getSupportFragmentManager(),list));

    }

    class MyFragmentAdapter extends FragmentPagerAdapter{

        List<Fragment> list;

        public MyFragmentAdapter(FragmentManager fm,List<Fragment> list) {
            super(fm);
            this.list=list;
        }

        /**
         * 返回需要展示的fragment
         * @param position
         * @return
         */
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        /**
         * 返回需要展示的fangment數量
         * @return
         */
        @Override
        public int getCount() {
            return list.size();
        }
    }
    class MyFragmentStateAdapter extends FragmentStatePagerAdapter{

        List<Fragment> list;

        public MyFragmentStateAdapter(FragmentManager fm,List<Fragment> list) {
            super(fm);
            this.list=list;
        }

        /**
         * 返回需要展示的fragment
         * @param position
         * @return
         */
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        /**
         * 返回需要展示的fangment數量
         * @return
         */
        @Override
        public int getCount() {
            return list.size();
        }
    }
}

在Activity我們通過以下代碼去初始化ViewPager所需要的數據

List<Fragment> list=new ArrayList<>();

Bundle bundle1=new Bundle();
bundle1.putString("Title","第一個Fragment");
bundle1.putInt("pager_num",1);
Fragment fg1=FragmentView.newInstance(bundle1);

Bundle bundle2=new Bundle();
bundle2.putString("Title","第二個Fragment");
bundle2.putInt("pager_num",2);
Fragment fg2=FragmentView.newInstance(bundle2);

Bundle bundle3=new Bundle();
bundle3.putString("Title","第三個Fragment");
bundle3.putInt("pager_num",3);
Fragment fg3=FragmentView.newInstance(bundle3);

Bundle bundle4=new Bundle();
bundle4.putString("Title","第四個Fragment");
bundle4.putInt("pager_num",4);
Fragment fg4=FragmentView.newInstance(bundle4);

list.add(fg1);
list.add(fg2);
list.add(fg3);
list.add(fg4);

viewPager.setAdapter(new MyFragmentAdapter(getSupportFragmentManager(),list));

  最後把數據時適配器MyFragmentAdapter設置給ViewPager,這樣就完成數據的填充。這裏有點要注意的是,Activity繼承自FragmentActivity,只有FragmentActivity才能內嵌fragment頁面,普通Activity是不行的。我們運行一下程序,效果如下:

到此我們對Fragment+ViewPager的使用方式已經有了比較清晰的瞭解了,本篇也就告一段落,下篇我們將通過實例來先一個通用的App首頁。歡迎繼續關注哈。

(app項目)源碼GitHub下載地址

ViewPager 從入門到帶你擼個啓動頁之ViewPager基礎入門(一)

ViewPager 從入門到帶你擼個啓動頁之Fragment+ViewPager(二)

ViewPager 從入門到帶你擼個啓動頁之實戰啓動頁(三)

ViewPager 從入門到帶你擼個啓動頁之實戰PageTransformer切換動畫特效(四)

發佈了65 篇原創文章 · 獲贊 3504 · 訪問量 230萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章