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: 

结论

  1. ViewPager默认会保留当前页和前后两页的内容,即一共三页。首页之前没有了所以只保留当前页和后一页;
  2. 对于不保留的内容,FragmentPagerAdapter 只进行到对Fragment的destroyView,不会destroy和detach;而FragmentStatePagerAdapter会执行destroy和detach,当划回去的时候会再次执行attach和create;
  3. 因此,FragmentPagerAdapter适用于数量较少的场景,用空间换时间;FragmentStatePagerAdapter适用于数量较多的场景,每次会执行destroy,节约内存。
posted @ 2020-03-31 12:31  PraveZ  阅读(2034)  评论(0编辑  收藏  举报