Search code examples
androidgridviewandroid-adapternotifydatasetchanged

notifyDataSetChanged() not working with GridView inside Fragment


I have a gridview inside my fragment that is populated by a BaseAdapter.

The problem is that in my adapter i have a favorite button, and when i click i want the button to change. But the logic in API is done, but my button just change when i reload page.

I tried using adapter.notifyDataSetChanged(); but didn't work.

My getView adapter code:

//Implementando os clicks
    itemHolder.imgFavorito.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!util.isLogado(context)) {
                ((MainActivity) context).selectDrawerItem(new LoginFragment());
            }

            try {
                SharedPreferences pref = context.getSharedPreferences("MyPref", 0);
                produtoFavorito(new favoritarProduto().execute(pref.getString("USID", "null"), item.getId() + "").get());
            } catch (Exception e) {
                e.printStackTrace();
            }

            fragment.notifyAdapterChanged();
        }
    });

In fragment.notifyAdapterChanged(); line a just call my Fragment that i recieve in constructor of adapter, and this is the function:

public void notifyAdapterChanged(){
    adapter.notifyDataSetChanged();
}

EDIT1: How my layout looks like https://i.sstatic.net/35IU9.png

EDIT2: My full Adapter

public class ProdutoAdapter extends BaseAdapter {

private LayoutInflater mInflater;
private List<ProdutoResumido> itens;
private HomeFragment fragment;

public ProdutoAdapter(Context context, List<ProdutoResumido> itens, HomeFragment fragment) {
    //Itens do listview
    this.itens = itens;
    //Objeto responsável por pegar o Layout do item.
    //mInflater = LayoutInflater.from(context);
    mInflater = (LayoutInflater) context.
            getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    this.fragment = fragment;
}

public int getCount() {
    return itens.size();
}

public ProdutoResumido getItem(int position) {
    return itens.get(position);
}

public long getItemId(int position) {
    return position;
}

public View getView(int position, View view, ViewGroup parent) {
    ItemSuporte itemHolder;
    //se a view estiver nula (nunca criada), inflamos o layout nela.
    if (view == null) {
        //infla o layout para podermos pegar as views
        view = mInflater.inflate(R.layout.lista_produtos_fg, null);

        //cria um item de suporte para não precisarmos sempre
        //inflar as mesmas informacoes
        itemHolder = new ItemSuporte();
        itemHolder.imgProduto = ((ImageView) view.findViewById(R.id.imgProduto));
        itemHolder.txtPreco = ((TextView) view.findViewById(R.id.txtPreco));
        itemHolder.imgFavorito = ((ImageView) view.findViewById(R.id.imgFavorito));
        itemHolder.txtNomeProduto = ((TextView) view.findViewById(R.id.txtNomeProduto));
        itemHolder.txtEstadoProduto = ((TextView) view.findViewById(R.id.txtEstadoProduto));
        itemHolder.imgLoja = ((ImageView) view.findViewById(R.id.imgLoja));
        itemHolder.txtNomeLoja = ((TextView) view.findViewById(R.id.txtNomeLoja));

        //define os itens na view;
        view.setTag(itemHolder);
    } else {
        //se a view já existe pega os itens.
        itemHolder = (ItemSuporte) view.getTag();
    }

    final Context context = view.getContext();

    //pega os dados da lista
    //e define os valores nos itens.
    final ProdutoResumido item = itens.get(position);
    Loja loja = new Loja();
    itemHolder.txtPreco.setText("R$ " + new DecimalFormat("#.00").format(item.getValor()));
    itemHolder.imgFavorito.setImageResource(produtoFavorito(item.getFavorito()));
    itemHolder.txtNomeProduto.setText(item.getNome());
    itemHolder.txtEstadoProduto.setText("ESTADO: " + item.getTempoUso());
    itemHolder.txtNomeLoja.setText(item.getLoja());
    try {
        if (item.getImagem() != null)
            new DownloadImageTask(itemHolder.imgProduto).execute("http://200.98.202.23/JustForMoms/" + item.getImagem());
        if (item.getLojaImg() != null)
            new DownloadImageTask(itemHolder.imgLoja).execute("http://200.98.202.23/JustForMoms/" + item.getLojaImg());
    } catch (Exception e) {
        e.printStackTrace();
    }


    //Implementando os clicks
    itemHolder.imgFavorito.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!util.isLogado(context)) {
                ((MainActivity) context).selectDrawerItem(new LoginFragment());
            }

            try {
                SharedPreferences pref = context.getSharedPreferences("MyPref", 0);
                produtoFavorito(new favoritarProduto().execute(pref.getString("USID", "null"), item.getId() + "").get());
            } catch (Exception e) {
                e.printStackTrace();
            }

            fragment.notifyAdapterChanged();
        }
    });


    //retorna a view com as informações
    return view;
}

private int produtoFavorito(Boolean favorito) {
    if (favorito)
        return R.drawable.favorite;
    else
        return R.drawable.notfavorite;
}

/**
 * Classe de suporte para os itens do layout.
 */
private class ItemSuporte {

    ImageView imgProduto;
    TextView txtPreco;
    ImageView imgFavorito;
    TextView txtNomeProduto;
    TextView txtEstadoProduto;
    ImageView imgLoja;
    TextView txtNomeLoja;
}


private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;

    public DownloadImageTask(ImageView bmImage) {
        this.bmImage = bmImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mIcon11 = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mIcon11;
    }

    protected void onPostExecute(Bitmap result) {
        bmImage.setImageBitmap(result);
    }
}

public class favoritarProduto extends AsyncTask<String, Void, Boolean> {

    private String retorno;
    private String url;

    @Override
    protected Boolean doInBackground(String... params) {
        String usID = params[0];
        String prodID = params[1];

        url = "http://200.98.202.23/JustForMoms/Produto/FavoritarProduto/" + usID + "/" + prodID;

        webclient client = new webclient(url);
        retorno = client.getmodel();

        if (retorno != null) {
            if (retorno.equals("\"incluido\"")) {
                return true;
            } else {
                return false;
            }


        }

        return false;
    }
}

}

EDIT 3:

 //Implementando os clicks
    itemHolder.imgFavorito.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!util.isLogado(context)) {
                ((MainActivity) context).selectDrawerItem(new LoginFragment());
            }

            try {
                SharedPreferences pref = context.getSharedPreferences("MyPref", 0);
                itemHolder.imgFavorito.setImageResource(produtoFavorito(new favoritarProduto().execute(pref.getString("USID", "null"), item.getId() + "").get()));
            } catch (Exception e) {
                e.printStackTrace();
            }

            ProdutoAdapter.this. notifyDataSetChanged();
        }
    });

Solution

  • Ok, You are calling favoritarProduto() which in turn makes a call to server to update the favorite status :)

    But you missed one simple thing :) Dude its Async call :) That means it takes time to execute the code inside doInBackground:) How can you expect the status to be updated and ready immediately as if it is synchronous call??? :)

    Modify the code as shown here

    public class favoritarProduto extends AsyncTask<String, Void, Boolean> {
        private String retorno;
        private String url;
    
        @Override
        protected Boolean doInBackground(String... params) {
            String usID = params[0];
            String prodID = params[1];
    
            url = "http://200.98.202.23/JustForMoms/Produto/FavoritarProduto/" + usID + "/" + prodID;
    
            webclient client = new webclient(url);
            retorno = client.getmodel();
    
            if (retorno != null) {
                if (retorno.equals("\"incluido\"")) {
                    return true;
                } else {
                    return false;
                }
    
    
            }
    
            return false;
        }
        @Override
        protected void onPostExecute(Boolean response) {
               //call your produtoFavorito fro the item holder based on prodID you have received :) 
        }
    
    }