论FragmentPagerAdapter与FragmentStatePagerAdapter的区别与使用场景

1,FragmentPagerAdapter:

FragmentPagerAdapter的注释有一段是这么写的:

* Implementation of {@link android.support.v4.view.PagerAdapter} that
* represents each page as a {@link Fragment} that is persistently
* kept in the fragment manager as long as the user can return to the page.
*
* <p>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.
意思是说:实现这个Adapter意味着呈现的每一个fragment 页面都是持久化保存到fragment manager 中,它最适合于一些静态页面(比如不需要请求网络数据)。在这里,用户访问过的每一个fragment实例都会保存到内存,即使fragment中的view会destroy。下面上一个例子:

package com.hai.ui;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;

import com.hai.R;
import com.hai.ui.fragment.MyFragment;
import com.hai.utils.MyLog;

public class FActivity extends FragmentActivity {
    private static final String TAG = "MainActivity";
    ViewPager viewPage;
    int PAGE=100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.lay_f);
        viewPage= (ViewPager) findViewById(R.id.viewPage);
        viewPage.setOffscreenPageLimit(1);//左右缓存各一个Fragment的View
        viewPage.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
                MyLog.e(TAG, "getItem: "+position );
                Fragment fragment=MyFragment.newInstance("fragment:"+position);
                return fragment;
            }

            @Override
            public int getCount() {
                return PAGE;
            }
        });
    }
}

package com.hai.ui.fragment;

import android.app.Activity;
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;

import com.hai.R;
import com.hai.utils.MyLog;

/**
 * Created by 黄海 on 10/1/2016.
 */

public class MyFragment extends Fragment {
    private static final String TAG = "MyFragment";
    String title;
    public static Fragment newInstance(String str){
        Fragment f=new MyFragment();
        Bundle b=new Bundle();
        b.putString("data",str);
        f.setArguments(b);
        return f;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        MyLog.d(TAG, "onAttach: "+title);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        title=getArguments().getString("data");
        MyLog.d(TAG, "onCreate: "+title);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
       View view= inflater.inflate(R.layout.lay_fragment,null);
        ((TextView)view.findViewById(R.id.tv)).setText(title);
        MyLog.d(TAG, "onCreateView: "+title);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        MyLog.d(TAG, "onActivityCreated: "+title);
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
        MyLog.d(TAG, "onViewStateRestored: "+title);
        super.onViewStateRestored(savedInstanceState);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        MyLog.d(TAG, "onViewCreated: "+title);
        super.onViewCreated(view, savedInstanceState);
    }

    @Override
    public void onStart() {
        MyLog.d(TAG, "onStart: "+title);
        super.onStart();
    }

    @Override
    public void onResume() {
        MyLog.d(TAG, "onResume: "+title);
        super.onResume();
    }

    @Override
    public void onPause() {
        MyLog.d(TAG, "onPause: "+title);
        super.onPause();
    }

    @Override
    public void onStop() {
        MyLog.d(TAG, "onStop: "+title);
        super.onStop();
    }

    @Override
    public void onDestroyView() {
        MyLog.d(TAG, "onDestroyView: "+title);
        super.onDestroyView();
    }

    @Override
    public void onDestroy() {
        MyLog.d(TAG, "onDestroy: "+title);
        super.onDestroy();
    }

    @Override
    public void onDetach() {
        MyLog.d(TAG, "onDetach: "+title);
        super.onDetach();
    }
}

FActivity的布局就一个ViewPage,MyFragment的布局就一个TextView,所以就不贴出来了。运行后通过Log看出:当Fragment初始化并且在Viewpage缓存内后会依次调用:
onAttach-->onCreate-->onCreateView-->onViewCreated-->onActivityCreated-->onViewStateRestored-->onStart-->onResume.当Fragment被移除缓存后,它就会执行:
onPause-->onStop-->onDestroyView.( 不会onDestroy,切记 )。比如进入app是Fragment1就是执行onAttach..到..onResume,当viewpage切换到第3页时,Fragment1就会执行onPause--到--onDestroyView。
viewPage.setOffscreenPageLimit()设置的是缓存多少个Fragment的View,但所以Fragment实例会一直缓存不销毁。
FragmentPagerAdapter使用场景:显示一些不会变化的View,静态View,不请求网络,Page数量不多;不适合一般app的主页,因为主页tab切换要求保持各Fragment生命周期只会在执行一次。

2,FragmentStatePagerAdapter

Implementation of {@link android.support.v4.view.PagerAdapter} that
* uses a {@link Fragment} to manage each page. This class also handles
* saving and restoring of fragment's state.
*
* <p>This version of the pager is more useful when there are a large number
* of pages, working more like a list view.  When pages are not visible to
* the user, their entire fragment may be destroyed, only keeping the saved
* state of that fragment.

这段注释是说,它会更适合有大量page的情况。因为它只缓存保存状态的Fragment,当Fragment变得不可见时(指Fragment不在Viewpage缓存内),不止是Fragment的View会destroy,连同Fragment实例也会destroy。也就是当Fragment被移除缓存后,它就会执行:onPause-->onStop-->onDestroyView-->onDestroy-->onDetach;

viewPage.setOffscreenPageLimit()设置的是缓存多少个Fragment实例(当然包括它的View了),Fragment离开缓存就是执行onDestroy-->onDetach

FragmentStatePagerAdapter使用场景:Page数量多的情况。其它和FragmentPagerAdapter无差别。


总结:当page数量少,用FragmentPagerAdapter;反之则用FragmentStatePagerAdapter;它们两的Fragment生命周期在ViewPage的切换过程中都会重复执行多次,所以它都不适用于App主页Tab。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值