Android ListView not refreshing after notifyDataSetChanged with data as Map

11,715

Solution 1

You must add a method to your CategoryAdapter to change the instance's list, like so

public class CategoryAdapter extends BaseAdapter {
ArrayList<Category> list = new ArrayList<Category>();
Context context;

public CategoryAdapter(Context context, Map<String, Category> categories) {
    this.context = context;
    list.clear();
    list.addAll(categories.values());
}

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

//ADD THIS METHOD TO CHANGE YOUR LIST
public void addItems(Map<String, Category> categories){
    list.clear();
    list.addAll(categories.values());
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHandler handler;

    LayoutInflater inflater = (LayoutInflater) context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.category_list_item, null);
        handler = new ViewHandler();
        handler.name = (TextView) convertView.findViewById(R.id.name);
        handler.count = (TextView) convertView.findViewById(R.id.count);
        convertView.setTag(handler);
    } else {
        handler = (ViewHandler) convertView.getTag();
    }
    Category category = list.get(position);
    handler.name.setText(category.getMenuName());
    handler.count.setText(category.getCount() + "");
    if (category.getCount() <= 0) {
        handler.count.setVisibility(View.INVISIBLE);
    } else {
        handler.count.setVisibility(View.VISIBLE);
    }

    return convertView;
}
}

and change your loadCategories like so (note that I call the addItems() before notifyDataSetChanged()

private void loadCategories() {
sampleDB = openOrCreateDatabase(AppConstants.DB_NAME, MODE_PRIVATE,
        null);
Cursor menuCursor = sampleDB.rawQuery("select * from menu", null);

categories.clear();
while (menuCursor.moveToNext()) {
    String menu = menuCursor.getString(menuCursor
            .getColumnIndex("name"));
    String id = menuCursor.getString(menuCursor.getColumnIndex("id"));
    Category category = new Category(menu, id);
    categories.put(id, category);
}
menuCursor.close();

//ADD CALL TO addItems TO UPDATE THE LIST OF THE categoryAdapter instance
categoryAdapter.addItems(categories);
categoryAdapter.notifyDataSetChanged();
}

Solution 2

have you tried saying:

categoryList.setAdapter(null);
categoryList.setAdapter(categoryAdapter);
Share:
11,715
Krish4906
Author by

Krish4906

Updated on June 05, 2022

Comments

  • Krish4906
    Krish4906 almost 2 years

    I used list adapter with map values as data. When I use adapter.notifyDataSetChanged(); the data in the list not updating. But if I replace the Map with ArrayList everything working fine. Following is my adapter code.

    public class CategoryAdapter extends BaseAdapter {
    ArrayList<Category> list = new ArrayList<Category>();
    Context context;
    
    public CategoryAdapter(Context context, Map<String, Category> categories) {
        this.context = context;
        list.clear();
        list.addAll(categories.values());
    }
    
    @Override
        public int getCount() {
            return list.size();
        }
    
    @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            final ViewHandler handler;
    
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            if (convertView == null) {
                convertView = inflater.inflate(R.layout.category_list_item, null);
                handler = new ViewHandler();
                handler.name = (TextView) convertView.findViewById(R.id.name);
                handler.count = (TextView) convertView.findViewById(R.id.count);
                convertView.setTag(handler);
            } else {
                handler = (ViewHandler) convertView.getTag();
            }
            Category category = list.get(position);
            handler.name.setText(category.getMenuName());
            handler.count.setText(category.getCount() + "");
            if (category.getCount() <= 0) {
                handler.count.setVisibility(View.INVISIBLE);
            } else {
                handler.count.setVisibility(View.VISIBLE);
            }
    
            return convertView;
        }
    }
    

    and my activity code is

    private void loadCategories() {
        sampleDB = openOrCreateDatabase(AppConstants.DB_NAME, MODE_PRIVATE,
                null);
        Cursor menuCursor = sampleDB.rawQuery("select * from menu", null);
    
        categories.clear();
        while (menuCursor.moveToNext()) {
            String menu = menuCursor.getString(menuCursor
                    .getColumnIndex("name"));
            String id = menuCursor.getString(menuCursor.getColumnIndex("id"));
            Category category = new Category(menu, id);
            categories.put(id, category);
        }
        menuCursor.close();
        categoryAdapter.notifyDataSetChanged();
    }
    

    in oncreate() method I have declared adapter as follows

    categoryAdapter = new CategoryAdapter(context, categories);
            categoryList.setAdapter(categoryAdapter);
            loadCategories();
    

    Every time I click on refresh button it calls loadCategories(); method. In the same code if I replace Map with ArrayList everything working fine.

    Now My question is why List is not refreshing with Map values. Please give me clarification regarding this.

    Thanks in advance.

  • Krish4906
    Krish4906 almost 10 years
    Working great. Thanks.
  • Krish4906
    Krish4906 almost 10 years
    without using addItems() if I repalce constructor with public CategoryAdapter(Context context, ArrayList<Category> categories) { this.context = context; list=categories; } it is working fine, but not with Map. Can you please explain me.
  • 0xDEADC0DE
    0xDEADC0DE almost 10 years
    Do you call that constructor in loadCategories() ?
  • Krish4906
    Krish4906 almost 10 years
    no. after updating of categories ArrayList, I have called notifyDataSetChanged() and it is working fine.
  • 0xDEADC0DE
    0xDEADC0DE almost 10 years
    Oh I see now. In your constructor, you assign categories to list. So if you update your categories, you update your list and then your data has changed
  • Krish4906
    Krish4906 almost 10 years
    Now I understood. Thank you for replay.