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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM