Android ViewPager + Fragment的实现与Fragment生命周期管理
ViewPager与Fragment合用可以实现滑动效果,并独立管理每个滑动页面的生命周期。ViewPager主要有两种Adapter用于适配填充Fragment,通过代码来查看其不同之处。
布局
Fragment的布局就只设置一个TextView。
在activity的布局中加入一个ViewPager
自定义适配器,继承两个不同的适配器基类
适配器需要传入一个FragmentManager参数,在activity中可以使用getSupportFragmentManager()获取到,直接传入即可。
FragmentPagerAdapter
private static class FragmentVPAdapter extends FragmentPagerAdapter{
private ArrayList<Fragment> fragments;
public FragmentVPAdapter(FragmentManager fm,ArrayList<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
FragmentStatePagerAdapter
private static class FragmentStateVPAdapter extends FragmentStatePagerAdapter{
private ArrayList<Fragment> fragments;
public FragmentStateVPAdapter(FragmentManager fm,ArrayList<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
}
Fragment
我们在Fragment中对每个生命周期函数都进行一次日志输出,观察其每一步变化。
public class ViewPagerContentFragment extends Fragment {
private String TAG = "Fragment";
private String sid;
public ViewPagerContentFragment(String sid) {
this.sid = sid;
TAG+=sid;
}
@Override
public void onAttach(Context context) {
Log.d(TAG, "onAttach: ");
super.onAttach(context);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreate: ");
super.onCreate(savedInstanceState);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.d(TAG, "onCreateView: ");
View inflate = inflater.inflate(R.layout.viewpager_fragment_sample, container,false);
TextView tv = inflate.findViewById(R.id.tv_in_vp);
tv.setText(sid);
return inflate;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
Log.d(TAG, "onActivityCreated: ");
super.onActivityCreated(savedInstanceState);
}
@Override
public void onStart() {
Log.d(TAG, "onStart: ");
super.onStart();
}
@Override
public void onResume() {
Log.d(TAG, "onResume: ");
super.onResume();
}
@Override
public void onPause() {
Log.d(TAG, "onPause: ");
super.onPause();
}
@Override
public void onStop() {
Log.d(TAG, "onStop: ");
super.onStop();
}
@Override
public void onDestroyView() {
Log.d(TAG, "onDestroyView: ");
super.onDestroyView();
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy: ");
super.onDestroy();
}
@Override
public void onDetach() {
Log.d(TAG, "onDetach: ");
super.onDetach();
}
}
执行
使用FragmentPageAdapter
初始阶段
application D/Fragment0: onAttach:
application D/Fragment0: onCreate:
application D/Fragment1: onAttach:
application D/Fragment1: onCreate:
application D/Fragment0: onCreateView:
application D/Fragment0: onActivityCreated:
application D/Fragment0: onStart:
application D/Fragment0: onResume:
application D/Fragment1: onCreateView:
application D/Fragment1: onActivityCreated:
application D/Fragment1: onStart:
application D/Fragment1: onResume:
向后滑动两次
application D/Fragment2: onAttach:
application D/Fragment2: onCreate:
application D/Fragment2: onCreateView:
application D/Fragment2: onActivityCreated:
application D/Fragment2: onStart:
application D/Fragment2: onResume:
application D/Fragment3: onAttach:
application D/Fragment3: onCreate:
application D/Fragment0: onPause:
application D/Fragment0: onStop:
application D/Fragment0: onDestroyView:
application D/Fragment3: onCreateView:
application D/Fragment3: onActivityCreated:
application D/Fragment3: onStart:
application D/Fragment3: onResume:
使用FragmentStatePageAdapter
初始阶段
application D/Fragment0: onAttach:
application D/Fragment0: onCreate:
application D/Fragment1: onAttach:
application D/Fragment1: onCreate:
application D/Fragment0: onCreateView:
application D/Fragment0: onActivityCreated:
application D/Fragment0: onStart:
application D/Fragment0: onResume:
application D/Fragment1: onCreateView:
application D/Fragment1: onActivityCreated:
application D/Fragment1: onStart:
application D/Fragment1: onResume:
向后滑动两次
application D/Fragment2: onAttach:
application D/Fragment2: onCreate:
application D/Fragment2: onCreateView:
application D/Fragment2: onActivityCreated:
application D/Fragment2: onStart:
application D/Fragment2: onResume:
application D/Fragment3: onAttach:
application D/Fragment3: onCreate:
application D/Fragment0: onPause:
application D/Fragment0: onStop:
application D/Fragment0: onDestroyView:
application D/Fragment0: onDestroy:
application D/Fragment0: onDetach:
application D/Fragment3: onCreateView:
application D/Fragment3: onActivityCreated:
application D/Fragment3: onStart:
application D/Fragment3: onResume:
结论
- ViewPager默认会保留当前页和前后两页的内容,即一共三页。首页之前没有了所以只保留当前页和后一页;
- 对于不保留的内容,FragmentPagerAdapter 只进行到对Fragment的destroyView,不会destroy和detach;而FragmentStatePagerAdapter会执行destroy和detach,当划回去的时候会再次执行attach和create;
- 因此,FragmentPagerAdapter适用于数量较少的场景,用空间换时间;FragmentStatePagerAdapter适用于数量较多的场景,每次会执行destroy,节约内存。