How to dynamically update a ListView with custom adapter?

40,951

Solution 1

Whenever you add new data you should do this:

adapter.notifyDataSetChanged()

For example:

database.insert(data);

myAdapter.notifyDataSetChanged();

OR:

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

Solution 2

After updating your adapter call

myAdapter.notifyDataSetChanged();

This will dynamically update the list view.

See this for more info LINK

Share:
40,951
user1118764
Author by

user1118764

Updated on May 18, 2020

Comments

  • user1118764
    user1118764 about 4 years

    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!");
      }
    }
    
  • user1118764
    user1118764 over 10 years
    Where do I do this? In the AsyncTask? Where exactly? I've made some changes at the end of my original post. Please take a look, thanks!
  • Usama Mudassar
    Usama Mudassar about 8 years
    Note all the intent I created are according to my logic in program. You can perform any task in onClick(View v) method/function