如何在自定义适配器中刷新ListView?

4

我使用自定义适配器从数据库中填充自定义列表视图。当数据库中的数据发生更改时,我无法更新列表视图。我已经尝试过使用notifysetdatachanged()方法,但它没有起作用。可能是因为我放置代码的方式不正确。请帮助我解决这个问题。谢谢。

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;
    }

}

[编辑]

最终我找到了解决问题的方法。我的列表视图应该首先检查列表视图的适配器是否为空。我将这段代码添加到我的onPostExecute中。感谢您的所有帮助。

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();
}


数据是否已经设置到了列表视图中? - Janki Gadhiya
3个回答

2

尝试这个

在您的onResume()中添加以下内容

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

我已经尝试了你的代码,但是出现了以下错误。java.lang.RuntimeException: Unable to resume activity {com.irmaelita.bpsgosurvey/com.irmaelita.bpsgosurvey.ContactActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.irmaelita.bpsgosurvey.CustomList.notifyDataSetChanged()'. 现在我该怎么办? - Irma Elita
如果我的答案对其他人有用,请点赞我的答案@IrmaElita。 - MurugananthamS

1
请尝试这些。
new Handler().post(new Runnable() {
    @Override
    public void run() {
        // Code here will run in UI thread
         adapter.notifyDataSetChanged();
    }
});

或者

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

我把你的第一段代码放在了我的onPostExecute中,但它没有起作用。它没有更新listview。我做错了什么吗? - Irma Elita

0

我认为你需要在包含列表视图的活动中实现加载器回调函数,并且你可以遵循这个答案 数据库更新后ListView未更新和adapter.notifyDataSetChanged();

更常见的编码方法是:

将此接口添加到您的活动中:

public class MyActivity extends Activity implementsLoaderManager.LoaderCallbacks<Cursor>

onCreate 方法中,设置适配器(注意此时游标为空):
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);

初始化加载器:

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

这会在后台线程中调用onCreateLoader(因此,如果您的查询运行时间很长,它不会阻塞UI线程)。当它完成时,在UI线程上调用onLoadFinished,您可以在其中交换新的光标。

在执行删除或更新操作后,请重新启动加载器:

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

这个调用了onLoaderReset方法,它会从适配器中移除现有的游标,然后再次调用onCreateLoader方法来替换一个新的游标。

最后添加这些方法:

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);
}

我是新手。我不知道如何将那段代码实现到我的代码中。你能否请教我如何做呢? - Irma Elita

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接