6

I am working with fragments and pushing new fragments on the backstack but when I rotate the device twice the fragment's onCreateView, onActivityCreated, and so on in the fragment life cycle methods are never called leaving a blank screen. This only occurs when a fragment has been added to the backstack or returning to the first fragment in the backstack.

Here is my activity's fragment handling methods:

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

    // Injection
    MormonChannel.injectActivity(this);

    setDrawerIndicatorEnabled(true);

    // Do not set currentNavigationItem here.
    NavigationItemSelectedEvent.NavigationItem navItem = null;
    Intent intent = getIntent();
    if (intent != null) {
        navItem = (NavigationItemSelectedEvent.NavigationItem)
        intent.getSerializableExtra(EXTRA_NAV_ITEM);
    }

    if (savedInstanceState == null) {
        FragmentManager fm = getSupportFragmentManager();
        fm.beginTransaction().replace(R.id.container, new FeatureListFragment()).commit();
        if (navItem != null) {
            onNavigationItemSelected(new NavigationItemSelectedEvent(navItem));
        } else {
            currentNavigationItem = NavigationItemSelectedEvent.NavigationItem.FEATURES;
        }
    }

}

@Subscribe
public void onNavigationItemSelected(NavigationItemSelectedEvent event) {

    if (currentNavigationItem == event.getNavigationItem()) {
        return;
    }
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.popBackStack();
    NavigationItemSelectedEvent.NavigationItem navigationItem = event.getNavigationItem();
    String name = navigationItem.getName();
    switch (navigationItem) {
        default:
        case FEATURES:
            // Nothing needs to be done it is already there.
            break;
        case AUDIO:
            fragmentManager.beginTransaction().replace(R.id.container,
                    CollectionListFragment.newInstance(prefs.getLanguageId(), prefs.getAudioCollectionId()))
                    .addToBackStack
                            (name).commit();
            break;
        case VIDEO:
            fragmentManager.beginTransaction().replace(R.id.container,
                    CollectionListFragment.newInstance(prefs.getLanguageId(), prefs.getVideoCollectionId()))
                    .addToBackStack(name).commit();
            break;
        case RADIO:
            fragmentManager.beginTransaction().replace(R.id.container,
                    CollectionListFragment.newInstance(prefs.getLanguageId(), prefs.getRadioCollectionId()))
                    .addToBackStack(name).commit();
            break;
        case HISTORY:
            fragmentManager.beginTransaction().replace(R.id.container, new HistoryFragment()).addToBackStack(name).commit();
            break;
        case DOWNLOADS:
            fragmentManager.beginTransaction().replace(R.id.container, new DownloadsFragment()).addToBackStack(name).commit();
            break;
        case PLAYLISTS:
            fragmentManager.beginTransaction().replace(R.id.container, new PlaylistFragment()).addToBackStack(name).commit();
            break;
    }
    currentNavigationItem = navigationItem;
}

Here is my CollectionListFragment Code:

 @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MormonChannel.injectFragment(this);
}

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

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

    listView.setDividerHeight(0);
    listView.setFastScrollEnabled(true);


    Bundle args = getArguments();
    if (args != null) {
        languageId = args.getLong(ARG_LANGUAGE_ID, -1L);
        collectionId = args.getLong(ARG_COLLECTION_ID, -1L);
        if (args.containsKey(ARG_SORT)) {
            sort = (Sort) args.getSerializable(ARG_SORT);
        }
    }

    if (collectionId == -1L || languageId == -1L) {
        // TODO Implement Empty Collection Text
    } else {
        collection = collectionManager.findByCollectionId(languageId, collectionId);
        getLoaderManager().initLoader(LOADER_ID, null, this);
    }

    titleEvent = new TitleChangeEvent(collection != null ? collection.getTitle() : getString(R.string.app_name));
    bus.post(titleEvent);
}

Manifest for activity:

<activity
    android:name=".activity.MainActivity"
    android:launchMode="singleTask">
    <meta-data
        android:name="android.app.default_searchable"
        android:value=".activity.SearchActivity"/>
</activity>
Ge3ng
  • 1,875
  • 1
  • 24
  • 38
  • This lecture might help you: http://stackoverflow.com/questions/8474104/android-fragment-lifecycle-over-orientation-changes it has some nice explaining answers – shkschneider Apr 30 '14 at 15:17
  • I am taking that into consideration via my Activity's onCreate method. – Ge3ng Apr 30 '14 at 15:21
  • 1
    You don't have a "configChanges" element for your Activity in your Manifest do you? That would prevent the Activity from being re-created on rotate. – NasaGeek Apr 30 '14 at 15:59
  • No the first rotation works but the second, third, ... do not. – Ge3ng Apr 30 '14 at 16:37

1 Answers1

1

In your CollectionListFragment Code, add call to setRetainInstance() method in the onCreate() method, with true as its argument:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
    MormonChannel.injectFragment(this);

}

Using setRetainInstance(true) ensures that when configuration changes occur activity will be killed but android will not destroy the fragment it is hosting.

Instead android will save the fragment state and detach the fragment from the activity. Also it wont destroy the fragment and so it wont create it later when hosting activity is created. So fragment will not receive calls to its onDestroy() and onCreate() methods.

Nipun Anand
  • 479
  • 2
  • 6
  • What about this photo (fragmnet lificycle)- https://www.safaribooksonline.com/library/view/android-programming-the/9780132869126/ciUIFragments/fragment_lifecycle.png - it makes all your anweir inirrelevant – Anton Kizema Apr 19 '15 at 17:12