Reputation: 448
I'm close to finishing my first Android app, but I'm fighting with an odd bug when I delete items from the SQLite DB that feeds a ListView in my app. The item gets deleted, and if I switch away from the ListView and back, it updates, but until I do that, the list doesn't update.
I've posted most of the class in question here: https://gist.github.com/2025973, but here's the relevant callback starting at line 56 in the file:
builder.setPositiveButton(R.string.button_delete,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
databaseConnector.deleteSimpleDie(arg3);
storedDiceAdapter.notifyDataSetChanged();
}
});
What am I doing wrong here? I'm sure it's something simple. I originally had the delete in an Async, but then I couldn't call the notifyDataSetChanged() at all, because it has to happen from the thread that created the Cursor.
UPDATE
Okay, this is pretty ghetto ( I think... ) but I've got it working, finally. Someone want to tell me how horribly wrong this is? Basically, I'm just re-instantiating the whole CursorAdapter inside the callback. It solves the problem, but I suspect it has some negative side effects I'm not aware of.
builder.setPositiveButton(R.string.button_delete,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
databaseConnector.deleteSimpleDie(arg3);
String[] from = new String[] { "name", "description" };
int[] to = new int[] { R.id.dice_name, R.id.dice_description };
storedDiceAdapter = new SimpleCursorAdapter(StoredDice.this,
R.layout.stored_dice_item, null, from, to);
setListAdapter(storedDiceAdapter);
}
});
Upvotes: 1
Views: 601
Reputation:
If you ever set the underlying data set to something new, your reference that the adapter is holding onto, will break. For example, this would break the adapter:
Globals.diceList = newDiceList;
When you want to fully change your data set, try something a little more like this, which will save you the trouble of having to constantly re-tool your adapter.
Globals.diceList.clear();
Globals.diceList.addAll(newDiceList);
Although in your case, you should be using a simple "remove" option instead. This will modify the contents of the list, without changing the location that it's referenced at. (Java is weird like that, I know.)
I wrote up a more in-depth look at it here.
Upvotes: 2
Reputation: 448
Well, as per the update on the question, it seems to be working. Not thrilled with that solution, but it's solved my immediate problem. Thank you everyone for the help.
Upvotes: 0
Reputation: 3312
I encountered similar problem earlier but I am not sure if it is exactly the same. You can give it a try.
It works for my case.
Slight modification to your code:
builder.setPositiveButton(R.string.button_delete,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
databaseConnector.deleteSimpleDie(arg3); // Update DB
storedDiceAdapter.setNewData(listData); // Update internal list
storedDiceAdapter.notifyDataSetChanged(); // Notify changes
}
});
Upvotes: 0
Reputation: 5177
i think your problem is the dialog:
public void onClick(DialogInterface dialog, int which) {
databaseConnector.deleteSimpleDie(arg3);
storedDiceAdapter.notifyDataSetChanged();
}
when show the dialog, your activity will be in onPause
or onStop
state , this time the activity dont refresh ui, so suggestion: when finish notifyDataSetChanged, you can dismiss the dialog, when onResume
method, also invoke notifyDataSetChanged
Upvotes: 0
Reputation: 2049
Try adding listView.invalidate() after notifyDataSetChanged()
Upvotes: 0