How to dynamically update a ListView with custom adapter?

adapter, android, android-listview, listview

Solution

Whenever you add new data you should do this:

adapter.notifyDataSetChanged()

For example:

database.insert(data);

myAdapter.notifyDataSetChanged();

OR:

myAdapter.mySetNewContentMethod(someNewContent);
myAdapter.notifyDataSetChanged();

Problem

I have a main activity that creates a `ListView` and a `Custom Adapter`. I'm able to populate the `ListView` if I have the List already created beforehand, but how do I populate it with dynamically fetched data? MainActivity ``` public class MainActivity extends Activity { private ListView myListView; private Context ctx; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.MainActivity); ctx = this; List<Items> myList = new ArrayList<Items>(); myList.add(new Item("Name 1", "Desc 1")); myList.add(new Item("Name 2", "Desc 2")); myList.add(new Item("Name 3", "Desc 3")); myList.add(new Item("Name 4", "Desc 4")); myList.add(new Item("Name 5", "Desc 5")); myListView = (ListView)findViewById(R.id.list); MyListAdapter myAdapter = new MyListAdapter(ctx,R.layout.listitem, myList); myListView.setAdapter(myAdapter); } } ``` MyListAdapter ``` public class MyListAdapter extends ArrayAdapter<Items> { private int resource; private LayoutInflater mLayoutInflater; public MyListAdapter ( Context ctx, int resourceId, List<Items> objects) { super( ctx, resourceId, objects ); resource = resourceId; mLayoutInflater = LayoutInflater.from( ctx ); } @Override public View getView ( int position, View convertView, ViewGroup parent ) { convertView = ( RelativeLayout ) mLayoutInflater.inflate( resource, null ); Items item = (Items) getItem( position ); TextView txtName = (TextView) convertView.findViewById(R.id.listName); txtName.setText(item.getName()); TextView txtDesc = (TextView) convertView.findViewById(R.id.listDescription); txtDesc.setText(item.getDesc()); return convertView; } } ``` Item ``` public class Item { private String name; private String desc; public Item(String name, String desc) { super(); this.name = name; this.desc = desc; } //getters and setters } ``` How can I modify my code such that a function in the background retrieves the items to the custom adapter and populates the ListView? I tried using an `AsyncTask` but couldn't manage to get it to work. Edit: Added the following `AsyncTask` in `MainActivity` after `onCreate()` just to test things out. It's working in that I can see the counting from 1 to 5 and then done. How do I get the `AsyncTask` to update my adapter and `ListView` though? What should `onCreate()` pass to the `AsyncTask` and what should `AsyncTask` return? ``` private class GetItems extends AsyncTask<Void, Integer, Void> { @Override protected void onPreExecute() { super.onPreExecute(); TextView myMsg = (TextView)findViewById(R.id.topMsg); myMsg.setText("Loading..."); } @Override protected Void doInBackground(Void... params) { TextView myMsg = (TextView)findViewById(R.id.topMsg); for (int i=1;i<=5;i++) { try { Thread.sleep(1000); publishProgress(i); } catch (InterruptedException e) { } } return null; } protected void onProgressUpdate(Integer... values) { TextView myMsg = (TextView)findViewById(R.id.topMsg); myMsg.setText(Integer.toString(values[0].intValue())); } @Override protected void onPostExecute(Void result) { TextView myMsg = (TextView)findViewById(R.id.topMsg); myMsg.setText("Done!"); } } ```

Original source

Related problems