I've made a custom BaseAdapter class to display registration keys in a ListView. Whenever I add another key to the list and call notifyDataSetChanged(), the ListView updates visually just fine. My data structure is simply an ArrayList of simple structures containing a few Strings and an int. However, when I try to clear the key list and call notifyDataSetChanged(), nothing happens visually. When I close and reopen the app, the list is empty, as it should be. Before calling notifyDataSetChanged() I now call notifyDataSetInvalidated(). This makes visuals update properly as soon as I clear the keys, but Google's documentation warns against using that method unless you're completely done using that adapter. When i register more keys after wiping them, they still show up in the ListView, which makes it seem like notifyDataSetInvalidated() is a working solution. Is there any danger associated with this method if I keep using the same BaseAdapter and ArrayList for the ListView? Is there a better solution? Here's my custom BaseAdapter implementation:
class KeyAdapter extends BaseAdapter implements Database.KeyRegistrationListener {
private ArrayList<Database.KeyDetails> keyInfo;
public KeyAdapter(ArrayList<Database.KeyDetails> keyInfo) {
this.keyInfo = keyInfo;
}
@Override
public int getCount() {
return keyInfo.size();
}
@Override
public Database.KeyDetails getItem(int position) {
return keyInfo.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int pos, View convertView, ViewGroup parent) {
TextView userID;
TextView appName;
TextView date;
TextView time;
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.registration_item, parent, false);
userID = (TextView) convertView.findViewById(R.id.user_id);
appName = (TextView) convertView.findViewById(R.id.app_name);
date = (TextView) convertView.findViewById(R.id.date_used);
time = (TextView) convertView.findViewById(R.id.time_used);
convertView.setTag(R.id.user_id, userID);
convertView.setTag(R.id.app_name, appName);
convertView.setTag(R.id.date_used, date);
convertView.setTag(R.id.time_used, time);
} else {
userID = (TextView) convertView.getTag(R.id.user_id);
appName = (TextView) convertView.getTag(R.id.app_name);
date = (TextView) convertView.getTag(R.id.date_used);
time = (TextView) convertView.getTag(R.id.time_used);
}
Database.KeyDetails key = getItem(pos);
userID.setText(key.userID);
appName.setText(key.appName);
date.setText(key.date);
time.setText(key.time);
return convertView;
}
@Override
public void notifyKeysUpdated(Database.KeyDetails newKeyDesc) {
if (newKeyDesc == null) {
keyInfo.clear();
notifyDataSetInvalidated();
notifyDataSetChanged();
} else{
keyInfo.add(newKeyDesc);
notifyDataSetChanged();
}
}
}
The notifyKeysUpdated() method is called by my wrapper class for a SQLite database whenever I add a key to the database. If my Database object feeds the listener null, it means all the keys in the database have been cleared and the ListView should be visually empty.
EDIT:
Since I started using notifyDataSetInvalidated(), the ListView no longer displays anything, including when I register new keys.