7

J'ai un problème avec ViewPager dans lequel ma ListView perd sa position de défilement.Fragment n'appelle pas onSaveInstanceState lorsque vous balayez ViewPager?

L'état de ListView peut facilement être stocké et restauré à l'aide:

@Override 
public View onCreateView (LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) 
{ 
    View v = inflater.inflate(R.layout.frag_cool_things, container, false); 

    AdvListView listView = (AdvListView) v.findViewById(R.id.lv0); 
    listView.setOnItemClickListener(mOnListItemClicked); 

    if (null != savedInstanceState) 
    { 
     listView.onRestoreListViewInstanceState(savedInstanceState.getParcelable("list_state")); 
    } 

    mListView = listView; 

    return v; 
} 

@Override 
public void onSaveInstanceState (Bundle outState) 
{ 
    super.onSaveInstanceState(outState); 

    outState.putParcelable("list_state", mListView.onSaveListViewInstanceState()); 
} 

Cependant, le problème est que lorsque des fragments sont glissées onDestroyView() est appelé mais jamais appelle onSaveInstanceState (Bundle outState).

Rotation de l'écran et tel restaure l'état ListView très bien, mais en balayant je ne peux pas comprendre comment restaurer la liste correctement.

Répondre

15

Mise à jour 12/17/11:
j'ai trouvé la bonne façon de sauvegarder le contenu des fragments. Vous devez utiliser FragmentStatePagerAdapter. Cet adaptateur enregistre correctement l'état du fragment! :)

VIEUX:
Eh bien, je trouve une façon de le faire .. S'il vous plaît partager vos commentaires si vous croyez que cela est un énorme non non! : P

Voici ma classe FragmentBase qui a fixé cette question:

public abstract class FragmentBase extends Fragment 
{ 
    private boolean mInstanceAlreadySaved; 
    private Bundle mSavedOutState; 

    @Override 
    public View onCreateView (LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) 
    { 
     if (null == savedInstanceState && null != mSavedOutState) { 
      savedInstanceState = mSavedOutState; 
     } 

     mInstanceAlreadySaved = false; 
     return onCreateViewSafe(inflater, container, savedInstanceState); 
    } 

    @Override 
    public void onSaveInstanceState (Bundle outState) 
    { 
     super.onSaveInstanceState(outState); 
     mInstanceAlreadySaved = true; 
    } 

    @Override 
    public void onStop() 
    { 
     if (!mInstanceAlreadySaved) 
     { 
      mSavedOutState = new Bundle(); 
      onSaveInstanceState(mSavedOutState); 
     } 

     super.onStop(); 
    } 

    public abstract View onCreateViewSafe (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState); 
} 
+0

ma propre solution temporaire consiste à écrire juste mon truc aux SharedPreferences dans OnPause(), et les retourner dans OnCreateView (...). Cependant, cela vous oblige à accéder à l'activité d'attachement pour obtenir les préférences partagées (getActivity(). GetSharedPreferences (...)), et vous pouvez également avoir besoin de supprimer explicitement les éléments indésirables lorsque l'activité est détruite (en fonction de ce que vous êtes stockage, ofc). J'espère que quelqu'un a un meilleur moyen! :) –

+0

S'il vous plaît voir la mise à jour de la réponse :) – Jona

+0

"FragmentPagerAdapter détachera chaque fragment lorsque vous balayez la liste, mais gardez-les en mémoire afin qu'ils puissent simplement être rattachés lorsque l'utilisateur fait défiler vers l'arrière. FragmentStatePagerAdapter vaut la peine d'être considéré car il va les supprimer, avec le désavantage d'avoir à être reconstruit lorsque l'utilisateur leur renvoie.Ainsi, si vous avez moins de fragments plus complexes, le FragmentPagerAdapter a du sens, mais considérez FragmentStatePagerAdapter pour les plus grands ensembles. (Android Dev Blog) –

Questions connexes