Irma Elita
Irma Elita

Reputation: 249

How to refresh listview in a custom adapter?

I made a custom listview with a custom adapter that populated from database. I can't update my listview whenever the data from database has changed. I have already tried using notifysetdatachanged() but it didn't work. Maybe it's because I putted the code in a wrong way. Please help me to solve this problem. Thanks.

ContactActivity.java

    public  void getImages2(){
        class GetImages2 extends AsyncTask<Void,Void,Void>{
            @Override
            protected void onPreExecute() {
                super.onPreExecute();

            }

            @Override
            protected void onPostExecute(Void v) {
                super.onPostExecute(v);
                loading.dismiss();
                customList = new CustomList(ContactActivity.this,GetAlImages2.imageURLs,GetAlImages2.bitmaps,GetAlImages2.code,GetAlImages2.name,GetAlImages2.phone,GetAlImages2.email);
                listView.setAdapter(customList);
                customList.notifyDataSetChanged();
  
                }
            @Override
            protected Void doInBackground(Void... voids) {
                try {
                    getAlImages2.getAllImages2();

                } catch (JSONException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }
        GetImages2 getImages = new GetImages2();
        getImages.execute();
    }

CustomList.java

public class CustomList extends ArrayAdapter<String> {
    private Bitmap[] bitmaps;
    private String[] urls;
    private String[] code;
    private String[] name;
    private String[] email;
    private String[] phone;

    private Activity context;

    public CustomList(Activity context,  String[] urls, Bitmap[] bitmaps, String[] code, String[] name, String[] phone, String[] email) {
        super(context, R.layout.activity_contact_item, urls);
        this.context = context;
        this.urls= urls;
        this.bitmaps= bitmaps;
        this.code= code;
        this.name= name;
        this.phone= phone;
        this.email =  email;
    }

}

[EDIT]

Finally I have found the solution of my problem. My listview should have checked first whether the listview's adapter is empty or not. I added this code to my onPostExecute. Thanks for all your help.

customList = new CustomList(ContactActivity.this,GetAlImages2.imageURLs,GetAlImages2.bitmaps,GetAlImages2.code,GetAlImages2.name,GetAlImages2.phone,GetAlImages2.email);
if(listView.getAdapter() == null){ //Adapter not set yet.
   listView.setAdapter(customList);
}
else{ //Already has an adapter
   listView.setAdapter(customList);
   customList.notifyDataSetChanged();
   listView.invalidateViews();
   listView.refreshDrawableState();
}

Upvotes: 4

Views: 7778

Answers (3)

Shruti
Shruti

Reputation: 5591

I think you need to implement loader callback to the activity that contains the listview .. and you can follow this answer Listview not updating after database update and adapter.notifyDataSetChanged();

The more common way to code this is:

Add this interface to your activity:

public class MyActivity extends Activity implementsLoaderManager.LoaderCallbacks<Cursor>

In onCreate, set up the adapter (note that the cursor is null at this point):

String[] from = new String[] { TodoTable.COLUMN_SUMMARY, TodoTable.COLUMN_ID};
int[] to = new int[] { R.id.label };
adapter = new SimpleCursorAdapter(this, R.layout.todo_row, null, from, to, 0);  //Note that the cursor is null
lw.setAdapter(adapter);

Initiate the loader:

getLoaderManager().initLoader(0, null, this);

This calls onCreateLoader in a background thread (so if your query is long running it won't block the UI thread). When it finishes, onLoadFinished is called on the UI thread where you can swap in the new cursor.

After you do a delete or update, restart the loader:

getLoaderManager().restartLoader(0, null, this);

This calls onLoaderReset which removes the existing cursor from the adapter and then calls onCreateLoader again to swap in a new one.

Finally add these methods:

public Loader<Cursor> onCreateLoader(int id, Bundle args)
{
    String[] from = new String[] { TodoTable.COLUMN_SUMMARY, TodoTable.COLUMN_ID};
    String where = TodoTable.COLUMN_DELETED + " = ?";

    Loader<Cursor> loader = new CursorLoader(this, TodoContentProvider.CONTENT_URI, from, where, new String[] {"0"}, null);     
    return loader;
}

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
{
    adapter.swapCursor(cursor);
}

public void onLoaderReset(Loader<Cursor> loader)
{
    adapter.swapCursor(null);
}

Upvotes: 0

MurugananthamS
MurugananthamS

Reputation: 2405

Try this

Inside your onResume() add this

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

Upvotes: 2

Ganesh Gudghe
Ganesh Gudghe

Reputation: 1387

please try these

new Handler().post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
         adapter.notifyDataSetChanged();
    }
});

OR

someActivity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
         adapter.notifyDataSetChanged();
        }
});

Upvotes: 1

Related Questions