I am trying to use a static class to pass value to a view instead of using intent as I have to pass a large amount of data. Sometimes I get this error and couldn't find out what is the main reason
Error :-
java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 101, found: 200
My Pager class
public class MemeDetailActivity extends AppCompatActivity implements OnDialogClickListner<Void> {
private ViewPager mPager;
private List<Datum> mList;
private ScreenSlidePagerAdapter pagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_meme_detail);
mList = DataResult.getInstance().getData();
DataResult.getInstance().resetData();
if (mList != null)
startPager(selected_position);
else
Toast.makeText(this, "Error loading data", Toast.LENGTH_SHORT).show();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}
private void startPager(int position) {
pagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(pagerAdapter);
pagerAdapter.notifyDataSetChanged();
mPager.setOffscreenPageLimit(0);
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
new Interactors(MemeDetailActivity.this).updateView(Util.getAccessToken(), mList.get(position).getId(), new OnFinishListner<ViewsRM>() {
@Override
public void onFinished(ViewsRM result) {
}
@Override
public void onFailed(String msg) {
}
});
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
mPager.setCurrentItem(position);
}
public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
//todo entry point 3 : showing the image in the viewpager
@Override
public Fragment getItem(int position) {
Fragment fragment = new fragment_mypager_new();
Bundle bundle = new Bundle();
if (frmMyMemes)
bundle.putParcelable("MY_DATA", myList);
bundle.putSerializable("DATA", mList.get(position));
fragment.setArguments(bundle);
return fragment;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
}
My static class
public class DataResult<T> {
private static DataResult instance;
private List<T> data = null;
protected DataResult() {
}
public static synchronized DataResult getInstance() {
if (instance == null) {
instance = new DataResult();
}
return instance;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
public void resetData() {
data = null;
}
}
How I call the activity
Intent intent = new Intent(getActivity(), MemeDetailActivity.class);
DataResult.getInstance().setData(mListA);
Sometimes this error occurs.
Here is my suggestion:
In your
DataResult
->getData()
return a copy of the data.
DataResult
is a singleton and holds the data. When your view gets the data, the view gets the data reference witch theDataResult
is holding. ThensetData()
would change thedata
reference. Here comes the IllegalStateException.Hope it would work :)
look at your code:
this code is use to refresh view when view change. it is also called
notifyDataSetChanged()
its optional ovverride method so you can remove it.
Take a look at this answer: ViewPager PagerAdapter not updating the View
or else you can Change the
FragmentStatePagerAdapter
toFragmentPagerAdapter
try using the following way:
I think your
DataResult
class is not necessary.According to your comment you are getting the error while you are updating the data set. I think you are getting data from some REST API or another web service. Then assign the data you gets from the API to a temporary Array List and update that temporary array list while you are getting new data. Don't touch the
mListA
variable until you finish receiving data. After complete getting data from the API assign the temporary array list you used tomListA
directly in one line.Then again call
This should solve your error.
It may because you first
setAdapter()
andnotifyDataSetChanged
in methodinitUI()
;Then, you instantiate the
List<?>
data in methodinitData()
, the two methods in different lifetime of fragment.It's the problem about fragment's lifecycle