Reputation: 249
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
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
Reputation: 2405
Try this
Inside your onResume()
add this
if (listvew!= null) {
listvew.invalidateViews();
}
adapter.notifyDataSetChanged();
Upvotes: 2
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