I started a new project using tabbed activity of Android Studio. It created an activity with ViewPager and 3 fragments = fragment1, fragment2 and fragment3. I changed fragment1 to have a listView and a TextView, that I initialize when the fragment is created. The data in the listView is read from an SQL database. When the application starts, fragment1 is displayed and the listView shows the data read from SQL. When I swipe from fragment1 to fragment2 and back, fragment1 shows the listview properly. However, when I swipe to fragment3 and back to fragment1 the listview data is lost and I get a blank screen, although the textview shows properly. When I change the application to have only 2 fragments it does not happen and I can swipe from fragment1 to fragment2 and back many times without any loss of data. The moment I add the 3rd fragment, the data is lost on first swipe to fragment3, but is not lost if I swipe between fragment 1 and fragment2 only. Any idea why is it happening?
-
It's impossible to tell exactly why it's happening without a reproducible example. The reason the problem doesn't occur with two Fragments is that the FragmentPagerAdapter keeps both Fragments alive, see here: http://stackoverflow.com/questions/8348707/prevent-viewpager-from-destroying-off-screen-views and here: http://stackoverflow.com/questions/10853611/viewpager-with-fragments-onpause-onresume – Daniel Nugent Mar 02 '16 at 19:55
-
The project is too big to post. If we do not find a solution soon I will create a small version to post. – Zvi Mar 02 '16 at 22:15
-
The project is too big to post. If we do not find a solution soon I will create a small version to post. Anyway, I tested further and found out that what happens is that the listview lost its adapter (listView.getAdapter() returns null). So before the page is re-displayed I now test for this condition and if it exists I recreate the adapter, and the list is displayed properly. Can this give you a hint on what happens? – Zvi Mar 02 '16 at 22:22
-
Issue i snow solved. – Zvi Mar 10 '16 at 22:22
2 Answers
This is happening because by default ViewPager
has a function named setOffscreenPageLimit(int i)
. This tells ViewPager
how many of the Fragments
need to store in memory. By default it is '2'. So when you swipe to Fragment 2 from Fragment 1 it will still keep Fragment 1 in memory and won't destroy it from memory. But when you swipe to Fragment 3 it will have Fragment 2 and Fragment 3 in memory so it will remove Fragment 1.
That's why when you come back to your first Fragment it have lost its views or data.
Try to use
mViewPager.setOffscreenPageLimit(your total fragment count +1);
Or much better solution
Do not replace
your fragment when you swipe in ViewPager
. Push
it to the backstack and when you comeback to it, Check for the backstack and if fragment is there then just Pop
it and display it.
Here is the code:
public void pushFragments(String tag, Fragment fragment) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
if (manager.findFragmentByTag(tag) == null) {
ft.add(R.id.frame_container, fragment, tag);
}
String tagOne="com........Frag_one"; //your fragment class name
String tagTwo="com........Frag_two";
String tagThree="com........Frag_three";
String tagFour="com........Frag_profile";
Fragment fragmentOne = manager.findFragmentByTag(tagOne);
Fragment fragmentTwo = manager.findFragmentByTag(tagTwo);
Fragment fragmentThree = manager.findFragmentByTag(tagThree);
Fragment fragmentFour = manager.findFragmentByTag(tagFour);
manager.executePendingTransactions();
// Hide all Fragment
if (fragmentOne != null) {
ft.hide(fragmentOne);
}
if (fragmentTwo != null) {
ft.hide(fragmentTwo);
}
if (fragmentThree != null) {
ft.hide(fragmentThree);
}
if (fragmentFour != null) {
ft.hide(fragmentFour);
}
// Show current Fragment
if (tag.equals(tagOne)) {
if (fragmentOne != null) {
ft.show(fragmentOne);
}
}
if (tag.equals(tagTwo)) {
if (fragmentTwo != null) {
ft.show(fragmentTwo);
}
}
if (tag.equals(tagThree)) {
if (fragmentThree != null) {
ft.show(fragmentThree);
}
}
if (tag.equals(tagFour)) {
if (fragmentFour != null) {
ft.show(fragmentFour);
}
}
ft.commit();
}
And Here is how you call it:
Fragment fragment = new Frag_one();
pushFragments(fragment.getClass().getName(),fragment);

- 1,872
- 1
- 13
- 28
Issue solved. The problem is due to the adapter keeping 3 fragments in memory, as pointed by @Daniel Nugent. The data in the pages is loaded from DB so that when the view is recreated, when fragments are destroyed and recreated as the user swipes, the listview adapter has lost the data, and one has to repopulate it. The problem does not appear on simple examples because usually the data presented is static and is loaded in the onCreateView method.

- 2,354
- 2
- 26
- 37