Handle fragmentation fragmentation during screen rotation (with sample code)

There are several similar answers, but not in this situation.


My situation is simple.

I have an Activity with two different layouts, one in Portrait, the other in Landscape.

In Portrait , I use <FrameLayout>and add Fragmentto it dynamically .

In Landscape, I use <fragment>, therefore, Fragment static . (it doesn't really matter)

First it starts with Portrait , then I added Fragmentsimply:

ListFrag listFrag = new ListFrag();
getSupportFragmentManager().beginTransaction()
        .replace(R.id.FragmentContainer, listFrag).commit();

where ListFrag extends ListFragment.

Then I rotate the screen. I found that listFrag is recreated in landscape mode. (In which I noticed that the method is onCreate()again called with a non-zero package)

I tried using setRetainInstance(false), like @NPike, in this post . But getRetainInstance()already falseby default. He does not do what I expected from. Can anyone explain this?


The snippet I'm dealing with is the ListFragmentone that does setListAdapter()at onCreate(). Therefore, the method cannot be used here. (or I don’t know how to apply). if (container == null) return null;

. if (bundle != null) setListAdapter(null); else setListAdapter(new ...); ListFragment? / , /, ? ( if (container == null) return null;)


Edit:

, , getSupportFragmentManager().beginTransaction().remove(getSupportFragmentManager().findFragmentById(R.id.FragmentContainer)).commit(); onSaveInstanceState(). .

  • , , WhatsApp TXT, . ( , ).

  • , . onCreate(Bundle) onRestoreInstanceState(Bundle). (1), onCreate(Bundle) onRestoreInstanceState(Bundle) , . Activity ( Bundle).

, , , getSupportFragmentManager()...replace(...).commit(); Portrait.


, :)

MainActivity.java

package com.example.fragremovetrial;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class MainActivity extends FragmentActivity {

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

        if (findViewById(R.id.FragmentContainer) != null) {
            System.out.println("-- Portrait --");       // Portrait
            ListFrag listFrag = new ListFrag();
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.FragmentContainer, listFrag).commit();
        } else {
            System.out.println("-- Landscape --");      // Landscape
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (findViewById(R.id.FragmentContainer) != null) {
            System.out.println("getRetainInstance = " +
                    getSupportFragmentManager().findFragmentById(R.id.FragmentContainer).getRetainInstance());
        }
    }
}

/activity _main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/FragmentContainer"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

layout-land/activity_main.xml ( )

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
</LinearLayout>

ListFrag.java

package com.example.fragremovetrial;

import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.widget.ArrayAdapter;

public class ListFrag extends ListFragment {
    private String[] MenuItems = { "Content A", "Contnet B" };

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

        System.out.println("ListFrag.onCreate(): " + (savedInstanceState == null ? null : savedInstanceState));

        setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, MenuItems));
    }
}

,

- -
ListFrag.onCreate(): null
getRetainInstance = false

( → )

ListFrag.onCreate(): Bundle [{android: view_state=android.util.SparseArray@4052dd28}]
- -
id 16908298 , .

( → )

ListFrag.onCreate(): Bundle [{android: view_state=android.util.SparseArray@405166c8}]
- -
ListFrag.onCreate(): null
getRetainInstance = false

( → )

ListFrag.onCreate(): Bundle [{android: view_state=android.util.SparseArray@4050fb40}]
- -
id 16908298 , .

( → )

ListFrag.onCreate(): Bundle [{android: view_state=android.util.SparseArray@40528c60}]
- -
ListFrag.onCreate(): null
getRetainInstance = false

, , . (, )

+5
4

, Activity. , :

, , - getSupportFragmentManager().beginTransaction().remove(getSupportFragmentManager().findFragmentById(R.id.FragmentContainer)).commit(); onSaveInstanceState(). ...

... .

onSaveInstanceState():

@Override
protected void onSaveInstanceState(Bundle outState) {
    if (isPortrait2Landscape()) {
        remove_fragments();
    }
    super.onSaveInstanceState(outState);
}

private boolean isPortrait2Landscape() {
    return isDevicePortrait() && (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE);
}

isDevicePortrait() :

private boolean isDevicePortrait() {
    return (findViewById(R.id.A_View_Only_In_Portrait) != null);
}

* , getResources().getConfiguration().orientation, , "". , Resources RIGHT AFTER, - onSaveInstanceState() !!

findViewById() ( - , ), private int current_orientation; current_orientation = getResources().getConfiguration().orientation; onCreate(). . , .

* remove_fragments() super.onSaveInstanceState().

( Activity. super.onSaveInstanceState(), Bundle, Activity. ###)

### . ? - , . - , .

+2

- onCreate()

if (savedInstanceState == null) {
     // Do fragment transaction.
}
+1

onCreate() ListFrag, . , , FrameLayout, , null.

if (findViewById(R.id.yourFrameLayout) != null) {
    // you are in portrait mode
    ListFrag listFrag = new ListFrag();
    getSupportFragmentManager().beginTransaction()
            .replace(R.id.FragmentContainer, listFrag).commit();
} else {
    // you are in landscape mode
    // get your Fragment from the xml
}

, , , ListFrag , , xml.

0

@midnite, , , . - . - , .

, - . DetailFragment.

OnCreate :

    fragment = (ToDoListFragment) getFragmentManager().findFragmentByTag(LISTFRAGMENT);
    frameDetailsFragment = (FrameLayout) findViewById(R.id.detailsFragment);
    detailsFragment = (DetailsFragment) getFragmentManager().findFragmentByTag(DETAILS_FRAGMENT);
    settingsFragment = (SettingsFragment) getFragmentManager().findFragmentByTag(SETTINGS_FRAGMENT);

-

    if (fragment == null){
        fragment = new ToDoListFragment();
        getFragmentManager().beginTransaction()
                .add(R.id.container, fragment, LISTFRAGMENT)
                .commit();
    }

:

  if (getFragmentManager().getBackStackEntryCount() > 0 ) {
        getFragmentManager().popBackStackImmediate();
    }

. -

  destroyTmpFragments();

:

  private void destroyTmpFragments(){
    if (detailsFragment != null && !detailsFragment.isVisible()) {
        Log.d("ANT", "detailsFragment != null, Destroying");
        getFragmentManager().beginTransaction()
                .remove(detailsFragment)
                .commit();

        detailsFragment = null;
    }

    if (settingsFragment != null && !settingsFragment.isVisible()) {
        Log.d("ANT", "settingsFragment != null, Destroying");
        getFragmentManager().beginTransaction()
                .remove(settingsFragment)
                .commit();

        settingsFragment = null;
    }
}

, , FragmentManager ( ). :

 04-24 23:03:27.164 3204    3204    D   ANT MainActivity onCreate()
 04-24 23:03:27.184 3204    3204    I   ANT DetailsFragment :: onCreateView
 04-24 23:03:27.204 3204    3204    I   ANT DetailsFragment :: onActivityCreated
 04-24 23:03:27.204 3204    3204    I   ANT DetailsFragment :: onDestroy
 04-24 23:03:27.208 3204    3204    I   ANT DetailsFragment :: onDetach

, onActivityCreated make - , . ( , cuz, remove is async) Fragment, (fargmnet placeholder), , , NullPointerException

, , , onActivityCreated ( :

 if (getFragmentManager().getBackStackEntryCount() > 0 ) {
        getFragmentManager().popBackStackImmediate();
    }

, , -

 if (frameDetailsFragment != null){
        Log.i("ANT", "frameDetailsFragment != null");

        if (EntryPool.getPool().getEntries().size() > 0) {
            if (detailsFragment == null) {
                detailsFragment = DetailsFragment.newInstance(EntryPool.getPool().getEntries().get(0), 0);
            }

            getFragmentManager().beginTransaction()
                    .replace(R.id.detailsFragment, detailsFragment, DETAILS_FRAGMENT)
                    .commit();
        }
    }
0

All Articles