简体   繁体   中英

Can't solve notifyDataSetChanged error in view Pager?

I have a View Pager in my App. The View pager gets the Imagepath from the JSON & shows in a ImageView. The View pager works for the first time. But when the values are changed, it returns a error.

But I have notified the PagerAdapter about the notifyDataSetChanged.

 java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 1, found: 0 Pager id: com.hello.hello:id/pager Pager class: class com.hello.hello.utils.ImageViewTouchViewPager Problematic adapter: class com.hello.hello.utils.ZoomAdapter

ASYNCTASK 1

public class FetchPromo extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            promoList = new ArrayList<String>();
            progress = new ProgressDialog(getActivity());
            progress.setMessage("Fetching Promotions from your Neighbouring store");
            progress.show();
            progress.setCanceledOnTouchOutside(false);
        }

        @Override
        protected Void doInBackground(Void... params) {
                String url = "http://46.101.126.31/mobileapp/gps/api.php?rquest=get_promotions&latitude=" + userLocation.getLatitude() + "&longitude=" + userLocation.getLongitude();
            Log.d("Path", url);
            try {
                OkHttpClient client = new OkHttpClient();
                Request request = new Request.Builder().url(url).build();
                Response response = client.newCall(request).execute();
                String jsonData = response.body().string();
                try {
                    JSONObject jsonObject = new JSONObject(jsonData);
                    store_name = jsonObject.getString("store_name");
                    JSONArray promo_path = jsonObject.getJSONArray("image_path");
                    Log.d("Path", store_name);
                    for (int i = 0; i < promo_path.length(); i++) {
                        String path = promo_path.getString(i);
                        promoList.add(path);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            store.setText(store_name);
            if (promoList.isEmpty()) {
                promoList.add(placeholder);
            }
            mZoomAdapter = new ZoomAdapter(getActivity(), promoList);
            mViewPager.setAdapter(mZoomAdapter);
            mZoomAdapter.notifyDataSetChanged();
            new FetchStore().execute();
            progress.dismiss();
        }
    }

AYNCTASK 2 (where the data has to be loaded again)

public class FetchPromoByID extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            promoList.clear();
            progress = new ProgressDialog(getActivity());
            progress.setMessage("Fetching Promotions from your Choosen store");
            progress.show();
            progress.setCanceledOnTouchOutside(false);
        }

        @Override
        protected Void doInBackground(Void... params) {
            String url = "http://46.121.116.31/mobileapp/gps/api.php?rquest=get_promotions_by_store_id&store_id=" + Choosen_id;

            Log.d("FetchPromoByID", url);
            try {
                OkHttpClient client = new OkHttpClient();
                Request request = new Request.Builder().url(url).build();
                Response response = client.newCall(request).execute();
                String jsonData = response.body().string();
                try {
                    JSONObject jsonObject = new JSONObject(jsonData);
                    JSONArray promo_path = jsonObject.getJSONArray("image_path");
                    store_name = jsonObject.getString("store_name");
                    Log.d("Path", store_name);
                    for (int i = 0; i < promo_path.length(); i++) {
                        String path = promo_path.getString(i);
                        promoList.add(path);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            mZoomAdapter = new ZoomAdapter(getActivity(), promoList);
            mViewPager.setAdapter(mZoomAdapter);
            mZoomAdapter.notifyDataSetChanged();
            new FetchStore().execute();
            progress.dismiss();
        }
    }

ADAPTER

public class ZoomAdapter extends PagerAdapter {

    private Context context;
    private ArrayList<String> IMAGES = new ArrayList<>();

    public ZoomAdapter(Context context, ArrayList<String> IMAGES) {
        this.IMAGES = IMAGES;
        this.context = context;
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    @Override
    public int getCount() {
        return IMAGES.size();
    }

    @Override
    public View instantiateItem(ViewGroup container, int position) {
        String url = IMAGES.get(position);
        PhotoView photoView = new PhotoView(container.getContext());

        // Now just add PhotoView to ViewPager and return it
        container.addView(photoView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

        Picasso.with(context)
                .load(url)
                .fit()
                .into(photoView);

        return photoView;
    }


    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }
}

FetchStore

public class FetchStore extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            storeList = new ArrayList<String>();
            storeID = new ArrayList<String>();
        }

        @Override
        protected Void doInBackground(Void... params) {

            String url = "http://46.101.116.31/mobileapp/gps/api.php?rquest=get_store";
            try {
                OkHttpClient client = new OkHttpClient();
                Request request = new Request.Builder().url(url).build();
                Response response = client.newCall(request).execute();
                String jsonData = response.body().string();
                try {
                    JSONObject jsonObject = new JSONObject(jsonData);
                    JSONArray storearray = jsonObject.getJSONArray("stores");
                    for (int i = 0; i < storearray.length(); i++) {
                        JSONObject storeobj = storearray.getJSONObject(i);
                        String store = storeobj.getString("name");
                        String ID = storeobj.getString("id");
                        storeList.add(store);
                        storeID.add(ID);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            choose.setVisibility(View.VISIBLE);
        }
    }

I have found many similar Questions like this. But none of the solution worked for me. Please guide me.

Thanks in Advance

I think your error is here (Async Task #2)

@Override
        protected void onPreExecute() {
            super.onPreExecute();
            promoList.clear();
            progress = new ProgressDialog(getActivity());
            progress.setMessage("Fetching Promotions from your Choosen store");
            progress.show();
            progress.setCanceledOnTouchOutside(false);
        }

You make promoList.clear() (set the count to 0),which used in ZoomAdapter instance without notifying.

So notify adapter there or make a temporary ArrayList and clear / addAll in onPostExecute

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM