88 votes

Une façon infaillible de gérer les fragments lors d'un changement d'orientation.

public class MainActivity extends Activity implements MainMenuFragment.OnMainMenuItemSelectedListener {

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

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager
            .beginTransaction();

    // add menu fragment
    MainMenuFragment myFragment = new MainMenuFragment();
    fragmentTransaction.add(R.id.menu_fragment, myFragment);

    //add content
    DetailPart1 content1= new DetailPart1 ();
    fragmentTransaction.add(R.id.content_fragment, content1);
    fragmentTransaction.commit();

}
public void onMainMenuSelected(String tag) {
  //next menu is selected replace existing fragment
}

J'ai besoin d'afficher deux vues de liste côte à côte, le menu à gauche et son contenu à droite. Par défaut, le premier menu est sélectionné et son contenu est affiché sur le côté droit. Le fragment qui affiche le contenu est le suivant :

public class DetailPart1 extends Fragment {
  ArrayList<HashMap<String, String>> myList = new ArrayList<HashMap<String, String>>();
  ListAdapter adap;
  ListView listview;

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

       if(savedInstanceState!=null){
        myList = (ArrayList)savedInstanceState.getSerializable("MYLIST_obj");
        adap = new LoadImageFromArrayListAdapter(getActivity(),myList );
        listview.setAdapter(adap);
       }else{
        //get list and load in list view
        getlistTask = new GetALLListTasks().execute();
    }

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

     @Override
      public void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
          outState.putSerializable("MYLIST_obj", myList );
        }
    }

Le onActivityCreated et le onCreateView sont appelés deux fois . Il existe de nombreux exemples utilisant des fragments. Comme je suis débutant dans ce domaine, je ne peux pas faire le lien entre l'exemple et mon problème. J'ai besoin d'un moyen infaillible pour gérer le changement d'orientation. Je n'ai PAS déclaré android:configChanges dans le fichier manifeste. J'ai besoin que l'activité soit détruite et recréée afin que je puisse utiliser une mise en page différente en mode paysage.

133voto

Warpzit Points 11150

Vous créez un nouveau fragment chaque fois que vous tournez l'écran dans votre activité. onCreate(); Mais vous maintenez aussi les anciens avec super.onCreate(savedInstanceState); . Donc, peut-être qu'il faut définir une balise et trouver le fragment s'il existe, ou passer un paquet nul à super.

Cela m'a pris un certain temps à apprendre et cela peut vraiment être une douleur lorsque vous travaillez avec des choses comme viewpager.

Je vous recommande de lire fragments un temps supplémentaire car ce sujet précis est couvert.

Voici un exemple de la façon de traiter les fragments lors d'un changement d'orientation régulier :

Activité :

public class MainActivity extends FragmentActivity {

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

        if (savedInstanceState == null) {
            TestFragment test = new TestFragment();
            test.setArguments(getIntent().getExtras());
            getSupportFragmentManager().beginTransaction().replace(android.R.id.content, test, "your_fragment_tag").commit();
        } else {
            TestFragment test = (TestFragment) getSupportFragmentManager().findFragmentByTag("your_fragment_tag");
        }
    }
}

Fragment :

public class TestFragment extends Fragment {

    public static final String KEY_ITEM = "unique_key";
    public static final String KEY_INDEX = "index_key";
    private String mTime;

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

        if (savedInstanceState != null) {
            // Restore last state
            mTime = savedInstanceState.getString("time_key");
        } else {
            mTime = "" + Calendar.getInstance().getTimeInMillis();
        }

        TextView title = (TextView) view.findViewById(R.id.fragment_test);
        title.setText(mTime);

        return view;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("time_key", mTime);
    }
}

21voto

Sergej Werfel Points 672

Un bon guide sur la façon de conserver les données entre les changements d'orientation et la recréation d'activité peut être trouvé dans les directives Android .

Résumé :

  1. faire en sorte que votre fragment puisse être conservé :

    setRetainInstance(true);
  2. Créer un nouveau fragment seulement si nécessaire (ou au moins prendre des données de celui-ci)

    dataFragment = (DataFragment) fm.findFragmentByTag("data");
    
    // create the fragment and data the first time
    if (dataFragment == null) {

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X