web-dev-qa-db-fra.com

Conserver l'objet Fragment en faisant pivoter

J'ai développé une application dans Honeycomb et j'utilise des fragments.
Ceci est mon application 

  • J'ai une activité (dites A1) et en ce qu'il y a un fragment 
  • Initialement, ce fragment contient l’objet un objet fragment dit (F1)
  • Ensuite, en fonction des actions de l'utilisateur, il peut être remplacé par d'autres objets F2, F3 .... 

Quel est mon problème  

Lorsque l'utilisateur fait pivoter le périphérique, l'activité est recréée et qui fait de F1 un objet fragment même si avant la rotation il
What is the way to retain the fragment object while rotating?
J'ai utilisé setRetainInstance(true); mais cela n'a pas fonctionné pour moi
Et j'ai ajouté le fragment par code dans ma fonction onCreate comme ceci 

@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.main);

   FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();

   Fragment homeFragment = new Home();
   fragmentTransaction.add(R.id.mainFragement, homeFragment);
   fragmentTransaction.commit();
}
47
Jithin

Par défaut, Android conservera les objets fragmentés. Dans votre code, vous définissez la variable homeFragment dans votre fonction onCreate. C’est pourquoi il s’agit toujours de homeFragment ou fl quel que soit le choix que vous avez établi dans onCreate.

Parce que chaque fois que vous faites pivoter, onCreate s'exécute et définit le fragment objet sur le premier  

Donc, la solution facile pour vous est de vérifier si le paquet savedInstanceState est null ou non et de définir l'objet fragment 

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if(null == savedInstanceState) {
        // set you initial fragment object 
    }
 }
61

Vous devez attribuer une étiquette unique à votre fragment et vérifier si ce fragment est déjà ajouté ou non à votre activité.

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    String tag = "my_fragment";
    FragmentManager fragmentManager = getFragmentManager();
    if(fragmentManager.findFragmentByTag(tag) == null) {
        FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
        Fragment homeFragment = new Home();
        fragmentTransaction.add(R.id.mainFragement, homeFragment, tag);
        fragmentTransaction.commit();
    }
}

Vérifier si savedInstanceState est null n'est pas un moyen sûr de vérifier si votre fragment est déjà défini - cela fonctionnera dans la plupart des cas, mais dans certains cas (par exemple, lorsque le périphérique est saturé en mémoire), Android peut tuer votre activité, casser votre application.

Pour voir cela en action, cochez la case "Ne pas garder les activités" dans les options de développement de l'appareil (le paramètre est disponible dans Android 4.0+, vous n'êtes pas sûr des versions précédentes). Lorsque vous ouvrez une nouvelle activité, votre première activité est détruite. Lorsque vous y revenez (en appuyant de nouveau), il est créé à nouveau et savedInstanceState est not null. Cependant, votre fragment ne fait plus partie de l'activité et vous devez l'ajouter à nouveau.

EDIT - Afficher le principe original mais avec SupportFragmentManager

public class ActivityAwesome extends AppCompatActivity
{
    private final String TAG = getClass().getSimpleName();
    private FragmentHome mHomeFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_layout);

        FragmentManager fragmentManager = getSupportFragmentManager();
        Fragment fragment = fragmentManager.findFragmentByTag(TAG);
        if(fragment == null)
        {
            // Create the detail fragment and add it to the activity using a fragment transaction.
            mHomeFragment = new FragmentHome();
            fragmentManager.beginTransaction()
                    .add(R.id.fragment_container, mHomeFragment, TAG)
                    .commit();
        }
        else
        {
            // get our old fragment back !
            mHomeFragment = (FragmentHome)fragment;
        }
    }
}

cela s'avère particulièrement utile si vous souhaitez manipuler le fragment (dans ce cas, mHomeFragment) après avoir fait pivoter votre appareil.

38
Ralf

Utilisez onAttachFragment() dans votre Activity pour réaffecter l'objet:

@Override
public void onAttachFragment(Fragment fragment) {
    if (fragment instanceof MyFragment)
        this.myFragment = (MyFragment) fragment;
}
3
Oded Breiner

Vous pouvez simplement définir la propriété RetainInstance dans OnCreate de la classe fragment.

public override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    RetainInstance = true;
}

Conserve l'objet Fragment en rotation

0
Shawinder Sekhon

J'ai défini une Fragment dans la présentation de l'activité, onSaveInstanceState dans la Fragment est appelée, mais la savedInstanceStateBundle dans la variable onCreatView est nulle.

La raison en était que ma Fragment n'avait pas d'identifiant XML:

Android:id="@+id/compass_fragment" ...
0
zomarev