从BaseAdapter调用notifyDataSetChanged时,ListView不会更新

时间:2010-12-07 11:03:09

标签: android android-widget

当基础数据发生变化时,我很难更新ListActivity。

我正在使用自定义(列表)适配器(CustomListAdapter)派生的vom BaseAdapter来使用自定义列表元素(CustomListElement)填充ListActivity。

有问题的元素可以通过用户交互或底层数据库中的更改随时间更改其基础数据。为了宣布所述更改,CustomListElement和CustomListAdapter对象可以注册DataSetObserver对象。

这实际上是这样做的(不幸的是发布整个代码会有点过分):

public class CustomListElement extends DataSetObservable {

    protected Object value;

    public void setValue(Object newValue) {
         this.value = newValue;
         notifyChanged();
    }
}

因此,CustomListElement通过继承DataSetObservable来提供registerDataSetObserver,并通过它的notifyChanged()方法宣布更改。

对于CustomListAdapter:

public class CustomListAdaper extends BaseAdapter {

    protected List<CustomListElement> elementList;

    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
        super.registerDataSetObserver(observer);

        for (CustomListElement element : elementList)
            element.registerDataSetObserver(observer);
    }
}

即。观察员是“通过”。

现在,在调用

setListAdapter(new CustomListAdapter(customElementList));
在ListActivity中,它应该在ListView的setAdapter方法中注册android.widget.AbsListView.AdapterDataSetObserver(从ListActivity的setListAdapter调用)。

在通知已注册的DataSetObserver对象任何更改时,应调用AdapterDataSetObserver的onChanged方法以及ListView的requestLayout。这应该(据我的理解)刷新ListView。

但是,ListView不会使用新数据进行更新。

我意识到已经指出notifyDataSetChanged和(可能)notifyChanged应该在runOnUiThread环境中运行,但这似乎无法解决问题。

我也意识到类似的问题出现了,但不是这个特定的Android类,并且答案不尽如人意。

我错过了什么吗?任何有关为什么会破坏以及如何解决这个问题的见解都非常感激。

3 个答案:

答案 0 :(得分:7)

registerDataSetObserver()接口的Adapter部分适用于可能有兴趣知道数据集何时更改的任何外部对象。 ListView对这些方法不应该真正感兴趣...如果BaseAdapter内容发生变化,您调用BaseAdapter.notifyDataSetChanged()会告诉ListView自行更新。

换句话说,你只需进行以下微小改动:

public void setValue(Object newValue) {
     this.value = newValue;
     notifyDataSetChanged();
}

实际上,由于您正在更改现有项目的状态(而不是添加新项目等),因此notifyDataSetInvalidated()将是更好的选择。

当然,除非您确实在其他地方有其他需要了解此数据的对象,否则您不需要任何DataSetObserver内容。

答案 1 :(得分:1)

问题已解决。问题实际上是在一个不同的点(这里没有提到的中间类没有对变化作出适当的反应)。初始代码非常有效。

非常感谢您的努力,

答案 2 :(得分:1)

adapter.notifyDataSetChanged();