简体   繁体   English

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

[英]ListView does not update when calling notifyDataSetChanged from a BaseAdapter

im am having difficulties to update a ListActivity when the underlying data changes. 我很难在基础数据发生变化时更新ListActivity。

I am using a custom (list) adapter (CustomListAdapter) derived vom BaseAdapter to fill a ListActivity with custom list elements (CustomListElement). 我正在使用自定义(列表)适配器(CustomListAdapter)派生的vom BaseAdapter来使用自定义列表元素(CustomListElement)填充ListActivity。

The elements in question can have their underlying data changed over time, either by user interaction or by changes in an underlying database. 有问题的元素可以通过用户交互或基础数据库中的更改随时间更改其基础数据。 In order to announce said changes, the CustomListElement and CustomListAdapter objects can register DataSetObserver objects. 为了宣布所述更改,CustomListElement和CustomListAdapter对象可以注册DataSetObserver对象。

This is in essence done like this (unfortunately posting the entire code would be overkill): 这本质上是这样做的(不幸的是发布整个代码会有点过分):

public class CustomListElement extends DataSetObservable {

    protected Object value;

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

Hence a CustomListElement provides registerDataSetObserver by inheritance from DataSetObservable and announces changes by means of it's notifyChanged() method. 因此,CustomListElement通过继承DataSetObservable来提供registerDataSetObserver,并通过它的notifyChanged()方法宣布更改。

And for the CustomListAdapter: 而对于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);
    }
}

Ie the observers are "handed through". 即观察者是“通过”。

Now, when invoking 现在,在调用时

setListAdapter(new CustomListAdapter(customElementList));

within a ListActivity this should register an android.widget.AbsListView.AdapterDataSetObserver within the setAdapter method of ListView (invoked from setListAdapter of ListActivity). 在ListActivity中,这应该在ListView的setAdapter方法中注册一个android.widget.AbsListView.AdapterDataSetObserver (从ListActivity的setListAdapter调用)。

Upon notifying the registered DataSetObserver objects of any change the onChanged method of the AdapterDataSetObserver and therefor requestLayout of the ListView should be invoked. 在通知已注册的DataSetObserver对象任何更改时,应调用AdapterDataSetObserver的onChanged方法以及ListView的requestLayout。 This should (to my understanding) refresh the ListView. 这应该(据我的理解)刷新ListView。

However, the ListView is not updated with the new data. 但是,ListView不会使用新数据进行更新。

I realize it has been pointed out that notifyDataSetChanged and (maybe) notifyChanged should be run within a runOnUiThread environment, however that does not seem to fix the issue. 我意识到已经指出notifyDataSetChanged和(可能)notifyChanged应该在runOnUiThread环境中运行,但是这似乎不能解决问题。

I also realize that similar questions came up, but not with this specific set of android classes, and with unsatisfying answers. 我也意识到类似的问题出现了,但不是这个特定的android类,并且有不满意的答案。

Am i missing anything? 我错过了什么吗? Any insight into why this breaks and how to fix it is greatly appreciated. 任何洞察为什么这个打破以及如何解决它非常感谢。

The registerDataSetObserver() part of the Adapter interface is for any external objects who might be interested to know when the data set changes. Adapter接口的registerDataSetObserver()部分适用于可能有兴趣知道数据集何时更改的任何外部对象。 A ListView shouldn't really be interested in these methods... if it's BaseAdapter content changes, you call BaseAdapter.notifyDataSetChanged() which will tell the ListView to update itself. ListView不应该对这些方法感兴趣...如果它的BaseAdapter内容发生了变化,你可以调用BaseAdapter.notifyDataSetChanged()来告诉ListView自己更新。

In other words you only need to make the following tiny change: 换句话说,您只需进行以下微小更改:

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

Actually, since you're changing the state of an existing item (rather than adding new ones etc) then notifyDataSetInvalidated() would be a better choice. 实际上,由于您正在更改现有项的状态(而不是添加新项等),因此notifyDataSetInvalidated()将是更好的选择。

And of course you don't need any of that DataSetObserver stuff unless you actually do have other objects elsewhere that need to know about this data. 当然,除非您确实在其他地方有其他需要了解此数据的对象,否则您不需要任何DataSetObserver。

adapter.notifyDataSetChanged();

The issue is resolved. 问题得到解决。 The problem was in fact at a different point (an intermediate class that was not mentioned here didn't react appropriately to changes). 问题实际上是在一个不同的点(这里没有提到的中间类没有对变化作出适当的反应)。 The initial code works beautifully. 初始代码工作得很漂亮。

Thanks alot for the effort, 非常感谢你的努力,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM