安卓 ListView notifyDataSetChanged

3
我拥有一个自定义listview, 每个条目都包含旋转的ProgressBar和单行文本视图。我总是仅更新列表中的第一项。问题在于,每次调用notifyDataSetChanged时,所有可见的视图都会被重新创建或作为convertView回收。
这种方法存在两个问题:
- 所有条目都被重新创建,而这很慢 - 而且我只更新第一个条目中的文本视图,这并不需要。 - 每次都会重新启动ProgressBar动画。
所以我想只保留第一个View的引用,并手动更新它。这个方法是有效的,但是它会随机抛出IllegalStateException(“适配器的内容已更改,但ListView没有收到通知。请确保您的适配器内容不是从后台线程修改的,而是只能从UI线程修改。”)
该如何解决这个问题?是否有一种方法可以通知ListView只有第一个条目发生了变化?即使有,ProgressBar动画仍将失败。是否有其他方式可以手动更新它?
谢谢。

你能展示一下进行更新的代码吗?从信息来看,你可能正在通过非UI线程(例如AsyncTask中的doInBackground())更新UI。 - momo
太复杂了,无法贴出来,但它在UI线程上。问题在于没有调用notifyDataSetChanged,正如我在问题中所解释的那样。 - Sebastian Nowak
我有相同的问题。我在UIThread中使用了关于列表和适配器的所有方法,但是这个异常会随机抛出。你怎么解决它? - atasoyh
1个回答

0

每当我需要更新列表视图中的单个项目时,我都会使用以下代码:

public void updateItemAt(int index) {
    View v = listView.getChildAt(index - listView.getFirstVisiblePosition());
    if (v != null) {
        //updates the view
    }
}

缺点是您需要在适配器中持有listView的引用。由于此代码通常从后台任务中调用,因此必须使用处理程序来调用它:

Handler myHandler = new Handler() {
    public void handleMessage(Message msg) {
        int index = msg.what;
        myAdapter.updateItemAt(index);
    };
};

//when task is complete:
myHandler.sendEmptyMessage(index);

请再次阅读问题。即使从UI线程进行更改,ListView也需要调用notifyDataSetChanged。您的解决方案也会随机抛出上述异常。 - Sebastian Nowak

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