Viewpager中的Fragment 滑動時儲存狀態的問題
阿新 • • 發佈:2018-11-24
之前遇到了在ViewPager中使用Fragment的情況,結果遇到了一個問題就是當viewPager划過去,再滑動回來後之前的fragment又回到了初始化的狀態。所以就研究了一下。網上搜了一下,大部分都是說這個FragmentPagerAdapter和FragmentStatePagerAdapter的。總結下來,主要是FragmentPagerAdapter會將每一個生成的fragment都儲存在記憶體中,因此比較適用於頁面相對於比較靜態,而且頁面比較少的情況。對於FragmentStatesPagerAdapter來說,只保留當前頁面,當頁面離開視線後,就會被消除,釋放其資源;而在頁面需要顯示時,生成新的頁面(就像 ListView 的實現一樣)。這麼實現的好處就是當擁有大量的頁面時,不必在記憶體中佔用大量的記憶體。
雖然說FragmentPagerAdapter是用來儲存狀態的,但是發現使用這個adapter後,滑動ViewPager,以前的頁面有初始化了一遍,並沒有儲存之前的資料。為了解決這個問題,將ViewPager中的Fragment的生命週期列印了一遍。列印過後發現,當用FragmentPagerAdapter時,根據viewPager的建立習慣,一般會建立左中右三個頁面。第一次會呼叫頁面的onAttach()、onCreate()、onCreateView()、onActivityCreated()、onStart()、onResume().並且第一次建立每個Fragment的時候會呼叫getItem()方法,之後便不會再呼叫這個方法了。之後再對ViewPager進行滑動的時候,比如 從3號頁面滑動到2號頁面時,分別呼叫的方法為:4號Fragment的onPause()、onStop()、
之後又對比看了一下用FragmentStatePagerAdapter來做介面卡時,所呼叫的方法第一次和FragmentPagerAdapter中建立fragment呼叫的方法一樣,也會呼叫
為了能夠實現在ViewPager中能夠儲存Fragment的狀態,採用了另外一種方法: 程式碼如下:
[java] view plain copy
- package com.example.viewpagerfragmentdemo;
- import java.util.List;
- import android.os.Bundle;
- import android.support.v4.app.Fragment;
- import android.support.v4.app.FragmentManager;
- import android.support.v4.app.FragmentPagerAdapter;
- import android.support.v4.app.FragmentStatePagerAdapter;
- import android.util.Log;
- import android.view.ViewGroup;
- public class MyAdapter extends FragmentPagerAdapter {
- public FragmentManager fm;
- public List<Fragment> list;
- public MyAdapter(FragmentManager fm) {
- super(fm);
- }
- public MyAdapter(FragmentManager fm, List<Fragment> list) {
- super(fm);
- this.fm = fm;
- this.list = list;
- }
- @Override
- public Fragment getItem(int position) {
- Fragment fragment = null;
- Log.i("sssssssssssss", "getItem");
- fragment = list.get(position);
- Bundle bundle = new Bundle();
- bundle.putString("id", "" + position);
- fragment.setArguments(bundle);
- return fragment;
- }
- @Override
- public int getCount() {
- return list.size();
- }
- @Override
- public Fragment instantiateItem(ViewGroup container, int position) {
- Fragment fragment = (Fragment) super.instantiateItem(container,
- position);
- fm.beginTransaction().show(fragment).commit();
- return fragment;
- }
- @Override
- public void destroyItem(ViewGroup container, int position, Object object) {
- // super.destroyItem(container, position, object);
- Fragment fragment = list.get(position);
- fm.beginTransaction().hide(fragment).commit();
- }
- }