2

The setup of my project is as follows

Activity has Fragment and it has ViewPager with pages supplied by FragmentStatePagerAdapter.

The data displayed by ViewPager is fetched from network.

When Activity is destroyed and restored, it tries to restore the Fragment that was visible in ViewPager when the Activity was destroyed. But the Fragment inside the ViewPager tries to access data structures that are not fully initialized, as a result crash happens.

I don't want the Fragment in ViewPager to be recreated.

One way that works is to pass null in super.Oncreate(savedInstance) of the Activity. But it will not allows me to restore state in any of other Fragments also which is not what I want.

What is the correct way to do it?

q126y
  • 1,589
  • 4
  • 18
  • 50
  • Why you just don't wont to destroy `fragment` with `ViewPager` or manage data connection `onDetach` or `onDestroyView` in `fragment`? – xAqweRx Aug 03 '16 at 13:36
  • As in overriding `onSaveInstanceState()` in the **`Fragment`** and NOT saving state (i.e. not calling super)? – dhke Aug 03 '16 at 13:48
  • @xAqweRx "Why you just don't wont to destroy fragment with ViewPager" I didn't get that. "manage data connection onDetach or onDestroyView in fragment? " It is managed in the parent `Fragment` [direct child of `Activity`] not int the child `Fragment`[part of the `ViewPager`] – q126y Aug 03 '16 at 13:49
  • So it means, that you should in parent `Fragment` ( direct child of `Activity` ) -> destroy adapter for `ViewPager` and `onActivityAttach` -> after connection is established -> create new adapter and set it to `ViewPager` – xAqweRx Aug 03 '16 at 13:56
  • @dhke no. say page 10 was visible in `viewpager` the `fragment` corresponding to page 10 is populated using data structure which is in inconsistent state, when the `Activity` is restored. I don't want that `fragment` to be `recreated`. I want that `fragment` to be gone, when `Activity` is destroyed. – q126y Aug 03 '16 at 13:59
  • @q126y I am a little confused. If I follow your answer, your hierarchy is Fragment->ViewPager->Fragment(s), isn't it? Which of the fragments are we now talking about? If you don't want the `ViewPager` to save state, tell the view pager not to save state (no re-created page fragments). If you want the whole `ViewPager` created from scratch, tell the outer fragment not to save its state. – dhke Aug 03 '16 at 14:08
  • @dhke `your hierarchy is Fragment->ViewPager->Fragment(s), isn't it?` yes. Yes I don't want `viewpager` to `recreate` the `fragment` that was last visible. `tell the outer fragment not to save its state. ` pass `null` in its `onsaveInstance`? I will try it. But I don't think it will solve the issue. The `childFragmentManager` will still have reference to the `Fragment` in `viewpager` and it will try to `recreate` it when `Activity` is created again. – q126y Aug 03 '16 at 14:18
  • @xAqweRx I tried that. I set the adapter of `viewpager` to `null` and reset the old adapter to have zero size and called its `notifydatasetChanged` and i did it aggresively in `onstop` to check, but it still tries to`recreate` the old fragment. – q126y Aug 03 '16 at 14:23
  • @q126y that shouldn't happen. The childFragmentManager [gets its information from the (outer) fragment's saved state](https://github.com/android/platform_frameworks_support/blob/master/v4/java/android/support/v4/app/Fragment.java#L1944). So if there is no state ... – dhke Aug 03 '16 at 14:26
  • @dhke it seems it shouldn't happen. I tried it is happening. :'( Is there any other reason for it to happen? – q126y Aug 03 '16 at 14:37
  • @dhke calling ` super.onSaveInstanceState(null);` inside class that extends `Fragment` does nothing, because the `Fragment.java` implementation of `onSaveInstanceState` is empty. So I get non `null` `Bundle` in `onCreate` of my `Fragment` – q126y Aug 03 '16 at 14:42
  • 1
    @q126y Narf, my bad. I didn't read the [code properly](https://github.com/android/platform_frameworks_support/blob/master/v4/java/android/support/v4/app/Fragment.java#L2108), the child fragment manager save gets called after `onSaveInstanceState()`. You probably really have to clear the `PagerAdapter` on detach. I feel dirty. – dhke Aug 03 '16 at 14:43
  • @dhkeI tried that. I set the adapter of `viewpager` to `null` and reset the old adapter to have zero size and called its `notifydatasetChanged` and i did it aggresively in `onstop` to check, but it still tries to recreate the old fragment. – q126y Aug 03 '16 at 14:50
  • 1
    @q126y `onStop()` is too late. The child fragment manager save its state in `onPause()`. One dirty hack that comes to mind is to remove the subparcel with tag `FragmentActivity.FRAGMENTS_TAG` from the restored bundle in `onCreate()` ... – dhke Aug 03 '16 at 14:55
  • @dhke That works. `FragmentActivity.FRAGMENTS_TAG` is not public, so value of `FragmentActivity.FRAGMENTS_TAG` needs to be used. And it has to be removed in `Activity` `onCreate` removing it in `Fragment` `onCreate` causes crash. If you come across better way to do it. Please let me know. If I come across, I will post it here. Thanks, for you help :) – q126y Aug 03 '16 at 15:14
  • 1
    @dhke It causes the `Fragment` to be recreated on orientaion Change also. I ended up doing `setAdapter(null)` in `onPause` and `setAdapter(originalAdapter)` in `onResume` – q126y Aug 03 '16 at 17:34
  • @q126y I had a very similar problem about a year ago but without the outer fragment. I ended up completely disabling state restore on the activity. The view is completely data-driven anyway (with data from a backend service), but it still feels kinda ugly not to have a knob *don't save and restore your state* – dhke Aug 03 '16 at 17:45
  • @dhke did you do that by passing `null` to `super.onCreate` of `Activity` or removing `FragmentActivity.FRAGMENTS_TAG` from `Bundle. If the latter, what argument did you present in the code review? – q126y Aug 03 '16 at 18:15
  • 1
    @q126y I pass `null` to `super.onCreate()` based on a runtime flag. – dhke Aug 03 '16 at 18:21
  • Try the Kathan Shah answer from this link https://stackoverflow.com/questions/40293118/remove-or-clear-all-fragments-from-viewpager. It worked for me. – Andre Rocha Apr 18 '18 at 18:09

0 Answers0