如何刷新Android listview?

UMA*_*MAR 423 android refresh android-listview

ListView添加/删除动态数据后如何刷新Android ?

Chr*_*Orr 522

调用notifyDataSetChanged()您的Adapter对象,一旦你在该适配器修改的数据.

notifyDataSetChanged()可以在此Google I/O视频中查看有关如何/何时通话的其他详细信息.

  • 您应该在UI线程上运行它.在UI线程中创建一个处理程序,然后将Runable发布到它 (23认同)
  • 再一次:notifyDataSetChanged()至少不适用于推荐的使用实践(读取不推荐).如果使用listview,游标适配器和内容提供程序,您可以尝试以下方法:gettLoaderManager().restartLoader().请参阅:http://stackoverflow.com/a/19657500/1087411我想在notifyDataSetChanged()上看到至少一些文档.在android中有很多东西留给黑盒测试. (11认同)
  • notifyDataSetChanged并不总是有效.我不确定为什么这是争论.有时您必须调用listView.setAdapter(适配器)来清除旧视图.另见:http://stackoverflow.com/a/16261588/153275 (4认同)
  • 我永远无法让 notifyDataSetChanged 工作。我可以清楚地看到我提供给适配器的集合已更改(元素已删除),但 notifyDataSetChanged 从未执行任何操作。不知道这个方法是不是刚刚坏了? (2认同)

Bob*_*obs 203

你也可以使用这个:

myListView.invalidateViews();
Run Code Online (Sandbox Code Playgroud)

  • 如果只需要REDRAW视图,这是正确的答案.例如,在用户登录后需要在listView的每个视图中公开更多信息或选项.这就是我需要做的,所以进行了投票.如果底层数据发生变化,那么使用notifyDataSetChanged()可能是个更好的主意. (22认同)

hcp*_*cpl 151

请忽略所有的invalidate(),invalidateViews(),requestLayout(),...这个问题的答案.

正确的做法(幸运的是,也标记为正确答案)是调用notifyDataSetChanged()适配器.

故障排除

如果调用notifyDataSetChanged()不起作用,则所有布局方法都无济于事.相信我ListView已正确更新.如果找不到差异,则需要检查适配器中的数据来自何处.

如果这只是一个你在内存中保存的集合,请在调用之前检查你是否实际删除了项目或将项目添加到集合中notifyDataSetChanged().

如果您正在使用数据库或服务后端,则必须在调用之前调用该方法再次检索信息(或操作内存数据)notifyDataSetChanged().

事情是这notifyDataSetChanged只有在数据集发生变化时才有效.如果您没有找到更改,那么这就是您要查看的地方.如果需要调试.

ArrayAdapter与BaseAdapter

我确实发现使用适配器来管理集合,就像BaseAdapter更好用.像ArrayAdapter这样的一些适配器已经管理了自己的集合,这使得更难获得适当的集合以进行更新.在大多数情况下,它实际上只是一个不必要的额外难度层.

UI线程

确实,必须从UI线程调用它.其他答案有关于如何实现这一点的例子.但是,只有在从UI线程外部处理此信息时才需要这样做.这是来自服务或非UI线程.在简单的情况下,您将从按钮单击或其他活动/片段更新数据.所以仍然在UI线程内.无需始终弹出runOnUiTrhead.

快速示例项目

可以在https://github.com/hanscappelle/so-2250770.git找到.只需在Android Studio(gradle)中克隆并打开项目即可.该项目的MainAcitivity构建了一个ListView包含所有随机数据的项目.可以使用操作菜单刷新此列表.

我为此示例ModelObject创建的适配器实现公开了数据集合

public class MyListAdapter extends BaseAdapter {

    /**
     * this is our own collection of data, can be anything we 
     * want it to be as long as we get the abstract methods 
     * implemented using this data and work on this data 
     * (see getter) you should be fine
     */
    private List<ModelObject> mData;

    /**
     * our ctor for this adapter, we'll accept all the things 
     * we need here
     *
     * @param mData
     */
    public MyListAdapter(final Context context, final List<ModelObject> mData) {
        this.mData = mData;
        this.mContext = context;
    }

    public List<ModelObject> getData() {
        return mData;
    }

    // implement all abstract methods here
}
Run Code Online (Sandbox Code Playgroud)

MainActivity中的代码

public class MainActivity extends Activity {

    private MyListAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ListView list = (ListView) findViewById(R.id.list);

        // create some dummy data here
        List<ModelObject> objects = getRandomData();
        // and put it into an adapter for the list
        mAdapter = new MyListAdapter(this, objects);
        list.setAdapter(mAdapter);

        // mAdapter is available in the helper methods below and the 
        // data will be updated based on action menu interactions

        // you could also keep the reference to the android ListView 
        // object instead and use the {@link ListView#getAdapter()} 
        // method instead. However you would have to cast that adapter 
        // to your own instance every time
    }

    /**
     * helper to show what happens when all data is new
     */
    private void reloadAllData(){
        // get new modified random data
        List<ModelObject> objects = getRandomData();
        // update data in our adapter
        mAdapter.getData().clear();
        mAdapter.getData().addAll(objects);
        // fire the event
        mAdapter.notifyDataSetChanged();
    }

    /**
     * helper to show how only changing properties of data 
     * elements also works
     */
    private void scrambleChecked(){
        Random random = new Random();
        // update data in our adapter, iterate all objects and 
        // resetting the checked option
        for( ModelObject mo : mAdapter.getData()) {
            mo.setChecked(random.nextBoolean());
        }
        // fire the event
        mAdapter.notifyDataSetChanged();
    }
}
Run Code Online (Sandbox Code Playgroud)

更多信息

关于listViews强大功能的另一篇好文章可以在这里找到:http://www.vogella.com/articles/AndroidListView/article.html

  • 你错了.notifyDataSetChanged()对我没有用,但invalidateViews()做得对. (16认同)
  • 这个答案真的帮助了我.出于某些特性原因,我将数组保留在内存中.为了解决这个问题,我现在在调用`notifyDataSetChanged()之前调用`adapter.clear()`和`adapter.addAll(Array <T>)`. (9认同)
  • 我有一个问题,列表中的实际元素不会改变,例如相同数量的元素.但问题在于它们呈现的方式需要改变.这意味着构建UI的适配器代码需要再次运行,然后正确隐藏列表行中的某些元素.notifyDataSetChanged()不起作用...... (6认同)
  • @hcpl,如果我在适配器的CheckBox的OnClickListener中,我该如何调用notifyDataSetChanged?invalidateViews正在完成工作.为什么invalidateViews调用错误的方法? (2认同)

Mar*_*ujo 42

随时调用runnable:

runOnUiThread(run);
Run Code Online (Sandbox Code Playgroud)

OnCreate(),你设置你的runnable线程:

run = new Runnable() {
    public void run() {
        //reload content
        arraylist.clear();
        arraylist.addAll(db.readAll());
        adapter.notifyDataSetChanged();
        listview.invalidateViews();
        listview.refreshDrawableState();
    }
};
Run Code Online (Sandbox Code Playgroud)


小智 11

我在listview的动态刷新方面遇到了一些问题.

在适配器上调用notifyDataSetChanged().

有关如何/何时调用notifyDataSetChanged()的一些其他细节可以在此Google I/O视频中查看.

在我的情况下,notifyDataSetChanged()无法正常工作[我从另一个类调用了notifyDataSetChanged].就在我在正在运行的Activity(Thread)中编辑ListView的情况下.该视频感谢克里斯托弗给出了最后的暗示.

在我使用的第二堂课

Runnable run = new Runnable(){
     public void run(){
         contactsActivity.update();
     }
};
contactsActivity.runOnUiThread(run);
Run Code Online (Sandbox Code Playgroud)

从我的Activity访问update().此更新包括

myAdapter.notifyDataSetChanged();
Run Code Online (Sandbox Code Playgroud)

告诉适配器刷新视图.据我所知,工作得很好.


小智 9

如果您正在使用SimpleCursorAdapter,请尝试在Cursor对象上调用requery().

  • 不推荐使用此方法. (13认同)

Nan*_*l T 5

如果您对ListView Refreshment不满意,可以查看这个片段,这是用于从DB加载listView,实际上你要做的只是重新加载ListView,在你执行任何CRUD操作后它不是最好的方法代码,但它会刷新ListView,如你所愿..

它对我有用....如果你找到更好的解决方案,请分享......

.......
......
do your CRUD Operations..
......
.....
DBAdapter.open();
DBAdapter.insert_into_SingleList();
// Bring that DB_results and add it to list as its contents....
                                            ls2.setAdapter(new ArrayAdapter(DynTABSample.this,
    android.R.layout.simple_list_item_1,                        DBAdapter.DB_ListView));
                                            DBAdapter.close();


归档时间:

查看次数:

475498 次

最近记录:

6 年,11 月 前