Android: Refresh ListView in first activity on return from second activity

Cristiano picture Cristiano · Jan 9, 2013 · Viewed 13.7k times · Source

I have a problem with list refresh when user closes one activity and returns to previous. I see that problem is very common but I can't solve it.

I overridden onResume method:

@Override
public void onResume() {
    super.onResume();
    populateList();
}

populateList() is a method where I populate listView with list of Strings:

arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item,list);
listView.setAdapter(arrayAdapter);

The problem is that when second activity is closed, new items are just added again in the ListView so I have every item doubled. Like it's not refreshed.

If I put notifyDataSetChanged() in onResume() it throws me nullPointerException because when activity is started first time there is no adapter initialized when activity is first time started.

I'm not sure how to handle this.

public class testActivity extends Activity {


    private int id=1;
    private ListView listView;
    private CustomArrayAdapter arrayAdapter;
    private ArrayList<String> list = new ArrayList<String>();
    ArrayList<Item> objectList = new ArrayList<Item>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

    }

    @Override
    public void onResume() {
        super.onResume();
        populateList();
    }

    private void populateList() {
        try {
            objectList = new GetAsyncTask(id).execute();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TimeoutException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        int size = objectList.size();
        String name;

        for (int i = 0; i < size; i++) {
            name = objectList.get(i).getName();
            list.add(name);
        }

        arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item,
                list);
        listView.setAdapter(arrayAdapter);
    }
}

Answer

mango picture mango · Jan 9, 2013

well right off the bat, you could easily knock this away with a simple conditional statement that performs the command only if the adapter isn't null:

    if (adapter != null) {
        adapter.notifyDataSetChanged();
    }

But this seems to me like, at a deeper level, your code could be re-factored somewhat to be more efficient, though not necessarily more functional.


do it like this:

private int id = 1;
private ListView listView;
private CustomArrayAdapter arrayAdapter;
private ArrayList<String> list = new ArrayList<String>();

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
}

@Override
public void onResume() {
    super.onResume();
    populateList();
}

private void populateList() {

    ArrayList<Item> objectList;
    try {
        objectList = new GetAsyncTask(id).execute();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } catch (ExecutionException e) {
        e.printStackTrace();
    } catch (TimeoutException e) {
        e.printStackTrace();
    }

    list.clear();
    for (int i = 0; i <objectList.size(); i++) {
        String name = objectList.get(i).getName();
        list.add(name);
    }
    if (arrayAdapter == null) {
        arrayAdapter = new CustomArrayAdapter(this, R.layout.symbol_item, list);
        listView.setAdapter(arrayAdapter);
    } else {
        arrayAdapter.notifyDataSetChanged();            
    }
}