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,節約內存。
