J'ai essayé l'exemple de code de l'API et cela n'a pas vraiment fonctionné alors j'ai implémenté le mien:
FragmentPagerSupport
public class FragmentPagerSupport extends FragmentActivity {
static final int NUM_ITEMS = 10;
MyAdapter mAdapter;
ViewPager mPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mAdapter = new MyAdapter(getSupportFragmentManager());
Log.i("Pager", "mAdapter = " + mAdapter.toString());
mPager = (ViewPager)findViewById(R.id.pager);
if (mPager == null)
Log.i("Pager", "mPager = null");
else
Log.i("Pager", "mPager = " + mPager.toString());
Log.i("Pager", "Setting Pager Adapter");
mPager.setAdapter(mAdapter);
}
public static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
Log.i("Pager", "MyAdapter constructor");
}
@Override
public int getCount() {
Log.i("Pager", "MyAdapter.getCount()");
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
Log.i("Pager", "MyAdapter.getItem()");
return TestFragment.newInstance(position);
}
}
public static class TestFragment extends Fragment {
public static TestFragment newInstance(int position) {
Log.i("Pager", "TestFragment.newInstance()");
TestFragment fragment = new TestFragment();
Bundle args = new Bundle();
args.putInt("position", position);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.i("Pager", "TestFragment.onCreateView()");
LinearLayout layout = (LinearLayout)inflater.inflate(R.layout.fragment_item, null);
int position = getArguments().getInt("position");
TextView tv = (TextView)layout.findViewById(R.id.text);
tv.setText("Fragment # " + position);
tv.setTextColor(Color.WHITE);
tv.setTextSize(30);
return layout;
}
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
>
<Android.support.v4.view.ViewPager
Android:id="@+id/pager"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
/>
</LinearLayout>
fragment_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
>
<TextView
Android:id="@+id/text"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:gravity="center"
Android:text="@string/hello"
/>
</LinearLayout>
Ma question est, au lieu de créer une nouvelle instance de Fragment
chaque fois que l'utilisateur glisse vers la gauche et la droite, comment puis-je enregistrer l'état d'un fragment (dans une structure de données), puis le restaurer?
Démo de l'API ne semble pas du tout avoir de code d'enregistrement des informations d'état.
Utilisez ViewPager.setOffscreenPageLimit()
dans FragmentActivity
ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
pager.setOffscreenPageLimit(2);
Voir plus sur Comment dire à mon FragmentPagerAdapter personnalisé de cesser de détruire mes fragments?
remplacez simplement cette méthode dans FragmentpagerAdapter
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// TODO Auto-generated method stub
super.destroyItem(ViewGroup container, int position, Object object);
}
supprimer super.destroyItem(ViewGroup container, int position, Object object);
à partir de votre code
pdate: Dans le getItem de MyAdapter vous retournez une nouvelle instance de votre Fragment. Android n'appellera pas getItem à chaque coup. Il appellera seulement getItem pour obtenir une nouvelle instance, mais réutilisera les instances existantes tant qu'elles sont disponibles.
À propos de la partie État de la démo. Je ne peux pas t'aider. Je pense que les techniques normales de restauration de l'état dans les fractions/activités s'appliquent ici, donc rien de spécial lors du chargement dans un ViewPager (mais je peux me tromper).
Si vous remplacez
public void destroyItem(View container, int position, Object object)
sans appeler super, le fragment ne sera pas détruit et sera réutilisé.
L'adaptateur doit être étendu à partir de FragmentStatePagerAdapter au lieu de FragmentPageAdapter et l'adaptateur gardera la référence de la position à l'élément de fragment. Sur le parent d'activité ou de fragment, définissez l'écouteur OnPageChangeListener pour que PageIndicator détecte la position de l'élément de fragment a été activé et met à jour l'état des données associées.
À propos de l'état des données de l'élément de fragment, je pense que devrait enregistrer/restaurer l'état du parent Activity ou Fragement.
L'adaptateur peut ajouter du code comme suit:
public static class MyAdapter extends FragmentStatePagerAdapter {
private SparseArray<TestFragment> mPageReferenceMap
= new SparseArray<TestFragment>();
...
@Override
public Object instantiateItem(ViewGroup viewGroup, int position) {
Object obj = super.instantiateItem(viewGroup, position);
//Add the reference when fragment has been create or restore
if (obj instanceof TestFragment) {
TestFragment f= (TestFragment)obj;
mPageReferenceMap.put(position, f);
}
return obj;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
//Remove the reference when destroy it
mPageReferenceMap.remove(position);
super.destroyItem(container, position, object);
}
public TestFragment getFragment(int key) {
return mPageReferenceMap.get(key);
}
...
}
J'espère que cette aide.
J'ai trébuché sur un terrain similaire ... Je voulais garder mes fragments enregistrés dans mon adaptateur pour éviter un rechargement inutile car je n'avais que 5 fragments dans le FragmentPagerAdapter
.
J'ai essentiellement dû créer un tableau et remplacer la méthode getItem(position)
:
private StoryListFragment[] fragmentsArray
= new StoryListFragment[getCount()];
public SectionsAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
if(fragmentsArray[position]!=null)
return fragmentsArray[position];
StoryListFragment storyListFragment = null;
switch(position){
case(0):
storyListFragment = StoryListFragment.newInstance(StoriesBank.NEWS);
break;
case(1):
storyListFragment = StoryListFragment.newInstance(StoriesBank.FEATURES);
break;
case(2):
storyListFragment= StoryListFragment.newInstance(StoriesBank.ARTS);
break;
}
fragmentsArray[position] = storyListFragment;
return storyListFragment;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
StoryListFragment fragment = (StoryListFragment) super.instantiateItem(container, position);
fragmentsArray[position] = fragment;
return fragment;
}