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。