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

Hau*_*uke 8 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,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);
    }
}
Run Code Online (Sandbox Code Playgroud)

即观察者是"通过".

现在,在调用时

setListAdapter(new CustomListAdapter(customElementList));
Run Code Online (Sandbox Code Playgroud)

在ListActivity中,这应该在ListView的setAdapter方法中注册一个android.widget.AbsListView.AdapterDataSetObserver(从ListActivity的setListAdapter调用).

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

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

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

我也意识到类似的问题出现了,但不是这个特定的android类,并且有不满意的答案.

我错过了什么吗?任何洞察为什么这个打破以及如何解决它非常感谢.

Reu*_*ton 7

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

换句话说,您只需进行以下微小更改:

public void setValue(Object newValue) {
     this.value = newValue;
     notifyDataSetChanged();
}
Run Code Online (Sandbox Code Playgroud)

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

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