Android ListView not refreshing after notifyDataSetChanged with data as Map
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);
Krish4906
Updated on June 05, 2022Comments
-
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 followscategoryAdapter = 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 almost 10 yearsWorking great. Thanks.
-
Krish4906 almost 10 yearswithout using
addItems()
if I repalce constructor withpublic 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 almost 10 yearsDo you call that constructor in
loadCategories()
? -
Krish4906 almost 10 yearsno. after updating of categories ArrayList, I have called notifyDataSetChanged() and it is working fine.
-
0xDEADC0DE almost 10 yearsOh I see now. In your constructor, you assign
categories
tolist
. So if you update yourcategories
, you update yourlist
and then your data has changed -
Krish4906 almost 10 yearsNow I understood. Thank you for replay.