0

I have the following situation and couldn't find a solution so far: In Activity A there is a ViewPager with a FragmentStatePagerAdapter. From Activity A you call Activity B. There you can change the some global data, what also affects the number of pages in the ViewPager in Activity A. So as soon I use the back button, to return to Activity A, I get the following Exception:

E/AndroidRuntime(1756): java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 121, found: 151 Pager id: com.example.blablabla:id/main_view_pager Pager class: class android.support.v4.view.ViewPager Problematic adapter: class com.example.blablabla.ActivityMain$MainViewPagerAdapter
E/AndroidRuntime(1756):     at android.support.v4.view.ViewPager.populate(ViewPager.java:962)
E/AndroidRuntime(1756):     at android.support.v4.view.ViewPager.populate(ViewPager.java:914)
...

I tried calling notifyDataSetChanged(); on the adapter at different places (onCreate, onRestart, onResume, onActivityResult) but nothing worked.

Another thing I tried was setting the adapter to null everytime Activity A is paused and then recreating it, when the activity is resumed. This avoids the crash, but 1. doesn't feel right and 2. the pages disappear shortly before the new activity becomes visible, so it does not look good.

So, how to handle this situation correctly?

Leif Sabellek
  • 173
  • 1
  • 9

3 Answers3

3

According to the error message you seem to set the adapter before you set the elements that are received by the adapter. ([...]Expected adapter item count: 121, found: 151[...])

So you should call PageAdapter.notifyDataSetChanged(); in your Activity B after changing the data set (because you should always call this method whenever a change happens). But passing that through Activities might be troublesome.

A solution for this could be the following explained by by alvarolb. alvarob used setTag() method in instantiateItem() for creating a new View and with findViewWithTag() you can retrieve it. You may want to take a look into Grimmace Code Sample which builds upon alvarolbs solution.

Another solution could be from rui.araujo by removing all Views and recreate them but that sounds pretty much to what you have done.

Community
  • 1
  • 1
DuKes0mE
  • 1,101
  • 19
  • 30
3

For me, calling notifyDataSetChanged on the pager adapter in onPause() fixed the problem: my list of data inside the pagerAdapter has changed its size (to 0, in my case), so the app crashed whenever it called getCount() on the pager adapter without notifying about the change first:

@Override
public void onPause() {

    //since our data might change (for example, in log out the data list is empty)
    //we need to notify the adapter so it wouldn't cause IllegalStateException
    if(pagerAdapter != null) {
        pagerAdapter.notifyDataSetChanged();
    }

    super.onPause();
}
limlim
  • 3,115
  • 2
  • 34
  • 46
1

Expected adapter item count: 121, found: 151

this expresses the data point to the same memory address, the one change, the other(as if your adapter item) also change, so you should copy the data backup, the one changes,the other would not change.

Robert
  • 5,278
  • 43
  • 65
  • 115
edo
  • 171
  • 2
  • 2
  • Yes this is true in my case. I am using a static class to pass value from one view to another and I am getting this crash error. Could you please tell me how to solve this issue. – viper Jan 09 '17 at 10:15
  • if you use list, you can use addAll(data). as if: public void addData(List data) { this.newList.addAll(data); } – edo Aug 29 '17 at 06:22