notifyDataSetChanged() doesn't work with my adapter for gridview

Denis picture Denis · Sep 7, 2013 · Viewed 9.9k times · Source

I have a GridView and adapter for GridView (BasketAdapter extends BaseAdapter).

I load data in GridView from sharedpref file. After I change data, I resave sharedpref file with data and call notifyDataSetChanged(). But notifyDataSetChanged() doesn't work unfortunately.

If I create new adapter and set it to my GridView, it works. Can anyone help me with this issue?

Here is my code:

public class FragmentBasket extends SherlockFragment {

    // my gridview
    GridView gvCatalogAllStoneBasket;
    // list of data from shared pref
    ArrayList<CatalogItem> catalogItemBasket = new ArrayList<CatalogItem>();
    ActionMode mode;
    public static CatalogItem catalogItem;
    // id variables for actionmode's actions
    static final int ID_DELETE = 1;
    static final int ID_EDIT = 2;
    // shared pref id string
    static String SHARED_PREFS_FILE = "basket";
    // my adapter
    BasketAdapter adapter = null;   

    public FragmentBasket() {

    }

    @Override
    public void onStart() {

        super.onStart();
        // loading saved data from file
        new GetCatalogAllStoneBasket().execute();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        Receiver receiver = new Receiver();
        IntentFilter intentFilterAdd = new IntentFilter("com.example.myproject.ADD_ITEM_BASKET");
        IntentFilter intentFilterEdit = new IntentFilter("com.example.myproject.EDIT_ITEM_BASKET");
        IntentFilter intentFilterDelete = new IntentFilter("com.example.myproject.DELETE_ITEM_BASKET");
        getActivity().registerReceiver(receiver, intentFilterAdd);
        getActivity().registerReceiver(receiver, intentFilterEdit);
        getActivity().registerReceiver(receiver, intentFilterDelete);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.right_panel_fragment_catalog_grid, container, false);

        gvCatalogAllStoneBasket = (GridView)view.findViewById(R.id.gvCatalogAllStoneBasket);

        gvCatalogAllStoneBasket.setOnItemLongClickListener(new OnItemLongClickListener() {

            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {


                // start action mode and send id of clicked item
                mode = getSherlockActivity().startActionMode(new ActionModeOfBasket(String.valueOf(view.getTag())));

                return false;
            }
        });

        return view;

    }

    private final class ActionModeOfBasket implements ActionMode.Callback
    {

        String itemId;

        public ActionModeOfBasket(String itemId) {

            // get id from clicked item
            this.itemId = itemId;
        }

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {


            menu.add(0, ID_EDIT, 0, "Edit")
            .setIcon(android.R.drawable.ic_menu_edit)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);

            menu.add(0, ID_DELETE, 1, "Delete")
            .setIcon(android.R.drawable.ic_menu_delete)
            .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);

            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {

            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {


            // get file
            SharedPreferences sPref = getActivity().getSharedPreferences(SHARED_PREFS_FILE, getActivity().MODE_PRIVATE);
            // open file for reading, writing
            BasketHelper bHelper = new BasketHelper(sPref, getActivity());

            switch (item.getItemId()) 
            {
            // if clicked del button
            case ID_DELETE:             
                // delete item
                bHelper.DelItem(itemId);
                mode.finish();
                catalogItemBasket = bHelper.GetAllItems();
                break;
            // if clicked edit button
            case ID_EDIT:               
                // edit item
                bHelper.EditItem(itemId, getFragmentManager());
                mode.finish();
                catalogItemBasket = bHelper.GetAllItems();

                break;  

            }

            return true;
        } 

        @Override
        public void onDestroyActionMode(ActionMode mode) {


        }

    }

    class GetCatalogAllStoneBasket extends AsyncTask<String, String, String>
    {

        @Override
        protected void onPreExecute() {

            super.onPreExecute();

        }

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

            SharedPreferences sPref = getActivity().getSharedPreferences(FragmentCatalogStonePosition.SHARED_PREFS_FILE, getActivity().MODE_PRIVATE);
            try {


                if(sPref.getString(FragmentCatalogStonePosition.TASK, null) != null)
                {

                    BasketHelper bHelper = new BasketHelper(sPref, getActivity());
                    catalogItemBasket = bHelper.GetAllItems();  
                }

            } catch (Exception e) {

                Log.d(MainActivity.tag, e.getMessage() + " " + e.getCause());
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(String result) {

            super.onPostExecute(result);

            adapter = new BasketAdapter(getActivity(), catalogItemBasket);
            gvCatalogAllStoneBasket.setAdapter(adapter);


        }

    }
    class Receiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent) {

            if(intent.getAction().toString() == "com.example.myproject.ADD_ITEM_BASKET")
            {


            }
            else if(intent.getAction().toString() == "com.example.myproject.EDIT_ITEM_BASKET")
            {                   

                // this code doesn't work (((
                adapter.notifyDataSetChanged();

                // this one successfully works              
                BasketAdapter bAdapter = new BasketAdapter(getActivity(), catalogItemBasket);
                gvCatalogAllStoneBasket.setAdapter(bAdapter);

            }
            else if(intent.getAction().toString() == "com.example.myproject.DELETE_ITEM_BASKET")
            {


            }


        }
    }
    class BasketAdapter extends BaseAdapter
    {

        Context context = null;
        ArrayList<CatalogItem> data = null;

        public BasketAdapter(Context context, ArrayList<CatalogItem> data) {

            this.context = context;
            this.data = data;

        }

        @Override
        public int getCount() {

            return data.size();
        }

        public CatalogItem getItem(int position) {

            return data.get(position);
        }

        @Override
        public long getItemId(int position) {

            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            View view = convertView;

            if(view == null)
            {

                LayoutInflater inflater = getLayoutInflater(null);
                view = inflater.inflate(R.layout.right_panel_fragment_catalog_grid_item, parent, false);

                CatalogItem item = getItem(position);
                ((TextView)view.findViewById(R.id.tvCatalogItemBasketName)).setText(item.name + " / " + item.code);

                Double gPrice = Double.valueOf(item.price) * Double.valueOf(item.count);
                ((TextView)view.findViewById(R.id.tvCatalogItemBasketCount)).setText(String.valueOf(item.count));
                ((TextView)view.findViewById(R.id.tvCatalogItemBasketGeneralPrice)).setText(String.valueOf(gPrice));
                ((TextView)view.findViewById(R.id.tvCatalogItemBasketDescription)).setText(item.description);

                final ImageView imgView = (ImageView)view.findViewById(R.id.ivCatalogItemBasketImage);
                String strURL = "http://myproject.ua/images/stock/" + item.folder + "/" + item.images + "_800x600.jpg";

                ImageLoaderConfiguration config = ImageHelper.ImageConfig(getActivity().getApplicationContext());

                DisplayImageOptions options = ImageHelper.ImageOptions();

                ImageLoader imageLoader = ImageLoader.getInstance();

                imageLoader.init(config);

                final ProgressBar pImgDialog = (ProgressBar)view.findViewById(R.id.pbImage);

                imageLoader.displayImage(strURL, imgView, options, new ImageLoadingListener() {

                    @Override
                    public void onLoadingStarted(String imageUri, View view) {

                        pImgDialog.setVisibility(View.VISIBLE);
                        imgView.setVisibility(View.GONE);

                    }

                    @Override
                    public void onLoadingFailed(String imageUri, View view, FailReason failReason) {

                        pImgDialog.setVisibility(View.GONE);
                        imgView.setVisibility(View.VISIBLE);

                    }

                    @Override
                    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {

                        pImgDialog.setVisibility(View.GONE);
                        imgView.setVisibility(View.VISIBLE);

                    }

                    @Override
                    public void onLoadingCancelled(String imageUri, View view) {

                        pImgDialog.setVisibility(View.GONE);
                        imgView.setVisibility(View.VISIBLE);

                    }
                });

                view.setTag(item.catalog_id);
            }

            return view;
        }

    }

}

Answer

malimo picture malimo · Sep 7, 2013

Your convertView isn't null in case the View is recycled, so your getView() should be something like this:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View view = convertView;

    if(view == null)
    {
        LayoutInflater inflater = getLayoutInflater(null);
        view = inflater.inflate(R.layout.right_panel_fragment_catalog_grid_item, parent, false);
    } 

        CatalogItem item = getItem(position);
        ((TextView)view.findViewById(R.id.tvCatalogItemBasketName)).setText(item.name + " / " + item.code);

        Double gPrice = Double.valueOf(item.price) * Double.valueOf(item.count);
        ((TextView)view.findViewById(R.id.tvCatalogItemBasketCount)).setText(String.valueOf(item.count));
        ((TextView)view.findViewById(R.id.tvCatalogItemBasketGeneralPrice)).setText(String.valueOf(gPrice));
        ((TextView)view.findViewById(R.id.tvCatalogItemBasketDescription)).setText(item.description);

        final ImageView imgView = (ImageView)view.findViewById(R.id.ivCatalogItemBasketImage);
        String strURL = "http://myproject.ua/images/stock/" + item.folder + "/" + item.images + "_800x600.jpg";

        ImageLoaderConfiguration config = ImageHelper.ImageConfig(getActivity().getApplicationContext());

        DisplayImageOptions options = ImageHelper.ImageOptions();

        ImageLoader imageLoader = ImageLoader.getInstance();

        imageLoader.init(config);

        final ProgressBar pImgDialog = (ProgressBar)view.findViewById(R.id.pbImage);

        imageLoader.displayImage(strURL, imgView, options, new ImageLoadingListener() {

            @Override
            public void onLoadingStarted(String imageUri, View view) {

                pImgDialog.setVisibility(View.VISIBLE);
                imgView.setVisibility(View.GONE);

            }

            @Override
            public void onLoadingFailed(String imageUri, View view, FailReason failReason) {

                pImgDialog.setVisibility(View.GONE);
                imgView.setVisibility(View.VISIBLE);

            }

            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {

                pImgDialog.setVisibility(View.GONE);
                imgView.setVisibility(View.VISIBLE);

            }

            @Override
            public void onLoadingCancelled(String imageUri, View view) {

                pImgDialog.setVisibility(View.GONE);
                imgView.setVisibility(View.VISIBLE);

            }
        });

        view.setTag(item.catalog_id);
    return view;
}

and since you have your own ArrayList inside your adapter, you have to update this one as well. Just add this method to your BasketAdapter:

public void changeModelList(List<CatalogItem> models) {
    this.data = models;
    notifyDataSetChanged();
}

and use it instead of notifyDataSetChanged(). it's not tested, but i think this is your problem.