luwionline
luwionline

Reputation: 186

SimpleAdapter notifyDataSetChanged

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

Answers (4)

luwionline
luwionline

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

Carlos Robles
Carlos Robles

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

desseim
desseim

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

nikhil_salunke
nikhil_salunke

Reputation: 150

just declare your ListAdapter as global variable

Upvotes: -1

Related Questions