【问题标题】:How to refresh listview in a custom adapter?如何在自定义适配器中刷新列表视图?
【发布时间】:2016-05-26 11:52:42
【问题描述】:

我使用从数据库填充的自定义适配器制作了一个自定义列表视图。每当数据库中的数据发生更改时,我都无法更新我的列表视图。我已经尝试过使用 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();
}

【问题讨论】:

  • 数据是否设置到列表视图??

标签: android listview


【解决方案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 中,但它不起作用。它没有更新列表视图。我是不是做错了什么?
【解决方案2】:

试试这个

在你的onResume() 中添加这个

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

【讨论】:

  • 我试过你的代码,然后我得到了这样的错误。 java.lang.RuntimeException:无法恢复活动 {com.irmaelita.bpsgosurvey/com.irmaelita.bpsgosurvey.ContactActivity}:java.lang.NullPointerException:尝试调用虚拟方法 'void com.irmaelita.bpsgosurvey.CustomList.notifyDataSetChanged() '。我现在该怎么办?
  • 如果我的回答对其他人有用,请点赞我的回答@IrmaElita
【解决方案3】:

我认为您需要对包含列表视图的活动实施加载程序回调 .. 您可以按照这个答案 Listview not updating after database update and 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);
}

【讨论】:

  • 我是新手。而且我不知道如何将该代码实现到我的代码中。你能告诉我怎么做吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-16
  • 1970-01-01
相关资源
最近更新 更多