Search code examples
javaandroidperformanceviewandroid-viewpager

When do we notify data changed on the PagerAdapter


I have seen several questions on this subject, I have tried adding the suggested onNotifyDataChanged but nothing seems to be working for me. I will appreciate any help, below is my class and inner class MyViewPagerAdapter , How can I stop fix this

java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 0,

Code:

public class SlideShowFragment extends DialogFragment {
    private final String TAG = SlideShowFragment.class.getSimpleName();
    private ArrayList<Image> images;
    private ProgressBar pd;


    /**
     * a simple newInstance
     *
     * @return slideShowFragment
     */
    public static SlideShowFragment newInstance() {
        SlideShowFragment slideShowFragment = new SlideShowFragment();
        return slideShowFragment;
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_slideshow_dialog_fragement, container, false);
        ViewPager viewPager = v.findViewById(R.id.viewpager);

        assert getArguments() != null;
        images = (ArrayList<Image>) getArguments().getSerializable("images");
        int selectedPosition = getArguments().getInt("position");

        pd = v.findViewById(R.id.img_progress);

        Log.e(TAG, "position: " + selectedPosition);
        Log.e(TAG, "images size: " + images.size());


            MyViewPagerAdapter myViewPagerAdapter = new MyViewPagerAdapter();
            //added this incase of crash #FIXME 5/25/2018
            myViewPagerAdapter.notifyDataSetChanged();
            viewPager.setAdapter(myViewPagerAdapter);






        return v;
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NORMAL, android.R.style.Theme_Black_NoTitleBar_Fullscreen);
    }

    /**
     * myViewPager Adapter inner class
     * I am using the Glide Library to help me display
     * images from the json data on my server.
     */
    class MyViewPagerAdapter extends PagerAdapter {

        private LayoutInflater layoutInflater;

        MyViewPagerAdapter() {
        }

        @TargetApi(Build.VERSION_CODES.KITKAT)
        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, int position) {

            layoutInflater = (LayoutInflater) Objects.requireNonNull(getActivity()).getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            assert layoutInflater != null;
            View view = layoutInflater.inflate(R.layout.image_fullscreen_preview, container, false);

            try {

                ImageView imageViewPreview = view.findViewById(R.id.image_preview);
                Image image = images.get(position);
                Glide.with(getActivity()).load(image.getLarge())
                        .thumbnail(0.5f)
                        .crossFade()

                        .diskCacheStrategy(DiskCacheStrategy.ALL)
                        .error(R.drawable.reload)
                        .listener(new RequestListener<String, GlideDrawable>() {
                            @Override
                            public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                                pd.setVisibility(View.VISIBLE);
                                return false;
                            }

                            @Override
                            public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target,
                                                           boolean isFromMemoryCache, boolean isFirstResource) {
                                pd.setVisibility(View.INVISIBLE);
                                return false;
                            }
                        })
                        .into(imageViewPreview);

                // pd.setVisibility(View.INVISIBLE);
                container.addView(view);
            }catch (ExecutionError e){
                Toast.makeText(getContext(),"Please Check Connection", Toast.LENGTH_SHORT).show();
            }


            return view;
        }

        @Override
        public int getCount() {


            return images.size();
        }

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


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

}

Solution

  • In my Point of view if you are using a adapter and assigned a empty or some basic datasets in that adapter and then again you want to add some more data in that same datasets and want to update the layout without loading it back to the initial consition then you can use "notifyDataChanges" this method will automatically load the data that has been added extra in the adpater or just updated by the user.

    For eg :

    private RecyclerView recyclerView;
    List<Home_Data> ModelHomeData = new ArrayList<>();  //taking a empty object of list to show
    recyclerView = (RecyclerView) view.findViewById(R.id.layout_modelBikeLinear);
    recyclerView.setAdapter(new ModelAdapter(ModelDataForView, R.layout.template_models , getContext()));
    recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
    

    In this case we have assigned an empty adapter to the view but i want to add more data and then change the view without loading it again and again so now i can add the data in the list data then will use "notifyDataChanged".

    for(int i = 0; i < response.length(); i++){
                    //SliderUtils sliderUtils = new SliderUtils();
                    Model_Data DataModelFile = new Model_Data();
                    try {
                        JSONObject jsonObject = response.getJSONObject(i);
                        DataModelFile.setModelId(jsonObject.getString("id"));
                        DataModelFile.setModelName(jsonObject.getString("name"));
                        DataModelFile.setModelPrice(jsonObject.getString("price"));
                        DataModelFile.setBikeImageUrl(jsonObject.getString("image"));
                        if ((Integer.parseInt(jsonObject.getString("available")) > 0) && (Integer.parseInt(jsonObject.getString("show")) > 0)) {
                            DataModelFile.setBikeAvailable(true);
                        }
                        else
                        {
                            DataModelFile.setBikeAvailable(false);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    ModelDataForView.add(DataModelFile);
                }
    adapter.notifyDataSetChanged();