Devesh Agrawal
Devesh Agrawal

Reputation: 9212

notifyDataSetChanged(); not working in android

This is my code.

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

    View v = inflater.inflate(R.layout.recycler_list, container, false);
    recyclerView = (RecyclerView) v.findViewById(R.id.recycler_view);

    RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 3);

    adapter = new FragmentBrandList.MyAdapter(Utility.getBrandMap(), getActivity());
    recyclerView.setAdapter(adapter);

    // asynchronous call
    query.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
                Brand brand = dataSnapshot1.getValue(Brand.class);
                brandMap.put(brand.getId(), brand);
            }

            Utility.setBrandMap(brandMap);
            adapter.notifyDataSetChanged();
        }

        @Override
        public void onCancelled(DatabaseError error) {
            // Failed to read value
            Log.w(TAG, "Failed to read value.", error.toException());
            Utility.displayToast("Failed to read value." + error.toException());
        }
    });
    return v;
}

Initially Utility.getBrandMap() is null. so noting is displaying. but in asynchronous call I am getting and updating the value and calling adapter.notifyDataSetChanged(); but still it doesn't update UI.

What is wrong here?

Edit: Adapter code

private class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    private List<Brand> brandList = new ArrayList<>();
    private Context context;

    public class MyViewHolder extends RecyclerView.ViewHolder {
        ImageView imageView;

        public MyViewHolder(View view) {
            super(view);
            imageView = (ImageView) view.findViewById(R.id.thumbnail);
        }
    }

    public MyAdapter(Map<String, Brand> brands, Context context) {
    //public MyAdapter(List<Brand> brands, Context context) {
        this.brandList = new ArrayList<>(brandMap.values());
        //this.brandList = brands;
        this.context = context;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.card_brand, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        if (brandList != null && brandList.size() > 0) {
            Brand brand = brandList.get(position);
            Glide.with(context).load(String.valueOf(brand.getImage()))
                    .error(R.drawable.placeholder)
                    .placeholder(R.drawable.placeholder)
                    .into(holder.imageView);
        }
    }

    @Override
    public int getItemCount() {
        return brandList.size();
    }
}

Upvotes: 0

Views: 135

Answers (2)

reVerse
reVerse

Reputation: 35264

You're passing an empty Map to the constructor of your MyAdapter. Once the asynchronous query is finished the Map is filled however the brandList in your adapter doesn't know anything about the new data. So what you want to do is to add the new items to the List inside the adapter.

Add the following method to the adapter:

public void addValues(Map<String, Brand> brands){
    brandList.clear();
    brandList.addAll(brands.values());
    notifyDataSetChanged();
}

and call it once the asynchronous query is finished.

Upvotes: 2

Sagar Jogadia
Sagar Jogadia

Reputation: 1350

Try this:

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

    View v = inflater.inflate(R.layout.recycler_list, container, false);
    recyclerView = (RecyclerView) v.findViewById(R.id.recycler_view);

    RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 3);

    adapter = new FragmentBrandList.MyAdapter(Utility.getBrandMap(), getActivity());
    recyclerView.setAdapter(adapter);

    // asynchronous call
    query.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
                Brand brand = dataSnapshot1.getValue(Brand.class);
                brandMap.put(brand.getId(), brand);
            }

            adapter.setBrandMap(brandMap);

        }

        @Override
        public void onCancelled(DatabaseError error) {
            // Failed to read value
            Log.w(TAG, "Failed to read value.", error.toException());
            Utility.displayToast("Failed to read value." + error.toException());
        }
    });
    return v;
}

And in adapter code:

private class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

    private List<Brand> brandList = new ArrayList<>();
    private Context context;

    public class MyViewHolder extends RecyclerView.ViewHolder {
        ImageView imageView;

        public MyViewHolder(View view) {
            super(view);
            imageView = (ImageView) view.findViewById(R.id.thumbnail);
        }
    }

    public MyAdapter(Map<String, Brand> brands, Context context) {
    //public MyAdapter(List<Brand> brands, Context context) {
        this.brandList = new ArrayList<>(brandMap.values());
        //this.brandList = brands;
        this.context = context;
    }

    public void setBrandMap(Map<String, Brand> brandMap){
      this.brandList = new ArrayList<>(brandMap.values());
      notifyDataSetChanged();
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.card_brand, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        if (brandList != null && brandList.size() > 0) {
            Brand brand = brandList.get(position);
            Glide.with(context).load(String.valueOf(brand.getImage()))
                    .error(R.drawable.placeholder)
                    .placeholder(R.drawable.placeholder)
                    .into(holder.imageView);
        }
    }

    @Override
    public int getItemCount() {
        return brandList.size();
    }
}

Upvotes: 2

Related Questions