Reputation: 186
I'm trying to refresh my ListView whenever I delete an item on it. But setting a notifyDataSetChanged();
is giving me this error:
Cannot refer to a non-final variable adapter inside an inner class defined in a different method.
The method notifyDataSetChanged() is undefined for the type ListAdapter.
ArrayList <HashMap <String, String> > data = dataHolder.getAllData();
dataHolder.getAllData();
if(data.size() !=0){
ListView lv = (ListView) findViewById(R.id.datalist);
ListAdapter adapter = new SimpleAdapter(MainActivity.this, data, R.layout.dataentry, new String[]{"unique_id","lastName"}, new int[]{R.id.unique_id,R.id.last_name});
lv.setAdapter(adapter);
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
AlertDialog.Builder adb = new AlertDialog.Builder(MainActivity.this);
adb.setTitle("Delete?");
adb.setIcon(android.R.drawable.ic_dialog_alert);
adb.setMessage("Delete selected item?");
adb.setCancelable(false);
adb.setNegativeButton("Cancel", null);
adb.setPositiveButton("Delete", new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
TextView uID = (TextView) findViewById(R.id.unique_id);
String unique_id = uID.getText().toString();
dataHolder.deleteData(unique_id);
adapter.notifyDataSetChanged();
}
});
adb.show();
return false;
}
});
}
Then it suggests to change it to:
((BaseAdapter) adapter).notifyDataSetChanged();
final ListAdapter adapter = new SimpleAdapter(MainActivity.this, data, R.layout.dataentry, new String[]{"unique_id","lastName"}, new int[]{R.id.unique_id,R.id.last_name});
But it's not refreshing the list after changing to that. What is the solution for this?
Upvotes: 0
Views: 5169
Reputation: 186
Solution found. Must remove first the item from the array list of the listview before notifying data set changed.
data.remove(position);
adapter.notifyDataSetChanged();
Upvotes: 0
Reputation: 10947
Make your adapter a field of the class instead of a local variable. Also, dont declare it using the ListAdapter interface, but a real class with the method that you need to use, so you dont need to cast, for instance
BaseAdapter adapter = new SimpleAdapter(....
and also...please note that the data colection of your adapter, is in data
, and you are deleting the item from dataHolder
, that i dont know what is. please check that actually data
is being changed when dataHolder
changes, otherwise the list wont change.
I think that is the problem. when you call notifyDataSetChanged()
it will check if data has changed. And probably it has not, and the adapter doesn't know how to get it again from dataHolder
. Thats why it is not working. you should pass a variable that is changed inside the dataHolder, or create your own adatper that receives the dataholder
as data, and call getAllData()
to retrieve the update when notifyDataSetChanged()
is called.
Other easier approach is that you create a public ArrayList <HashMap <String, String> > data
in your dataHolder
. That data
is modified when you call deleteData
or when you insert data to the dataHodler
. And that dataHolder.data
is what you pass to the adapter in the constructor:
new SimpleAdapter(MainActivity.this, dataHolder.data, R.layout.dataentry, new String[]{"unique_id","lastName"}, new int[]{R.id.unique_id,R.id.last_name});
Upvotes: 1
Reputation: 8258
To reference adapter
from within the AlertDialog.OnClickListener
, you need it to be final (that's basically what the error tells you). So just declare it final
:
final BaseAdapter adapter = new SimpleAdapter(MainActivity.this, data, R.layout.dataentry, new String[]{"unique_id","lastName"}, new int[]{R.id.unique_id,R.id.last_name});
You could also just grab it from the parameters you are called with:
@Override
public boolean onItemLongClick(final AdapterView<?> adapterView, View arg1, int arg2, long arg3) {
// ...
final Adapter adapter = adapterView.getAdapter();
if (adapter instanceof BaseAdapter) {
((BaseAdapter)adapter).notifyDataSetChanged();
} else {
throw new RuntimeException("Unexpected adapter");
}
for example.
Upvotes: 3