从BaseAdapter调用notifyDataSetChanged时ListView控件不更新 [英] ListView does not update when calling notifyDataSetChanged from a BaseAdapter

查看:725
本文介绍了从BaseAdapter调用notifyDataSetChanged时ListView控件不更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即时通讯时遇到困难更新ListActivity当底层数据的变化。

im am having difficulties to update a ListActivity when the underlying data changes.

我使用的是自定义(表)适配器(CustomListAdapter)来源VOM BaseAdapter来填充自定义列表元素的ListActivity(CustomListElement)。

I am using a custom (list) adapter (CustomListAdapter) derived vom BaseAdapter to fill a ListActivity with custom list elements (CustomListElement).

在问题可以有自己的底层数据元素随时间的变化,无论是通过用户交互或改变底层数据库中。为了宣布说变化,CustomListElement和CustomListAdapter对象可以注册DataSetObserver对象。

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.

这在本质上是这样的(可惜张贴整个code会矫枉过正)完成的:

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();
    }
}

因此​​,一个CustomListElement提供registerDataSetObserver通过继承从DataSetObservable和手段宣布改变它的notifyChanged()方法。

Hence a CustomListElement provides registerDataSetObserver by inheritance from DataSetObservable and announces changes by means of it's notifyChanged() method.

和为CustomListAdapter:

And for the 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);
    }
}

即。该观察员通过递。

I.e. the observers are "handed through".

现在,在调用的时候

setListAdapter(new CustomListAdapter(customElementList));

在一个ListActivity这应该注册一个<一个href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/2.2_r1.1/android/widget/AdapterView.java#AdapterView.AdapterDataSetObserver">android.widget.AbsListView.AdapterDataSetObserver ListView控件的setAdapter方法​​中(从ListActivity的setListAdapter调用)。

within a ListActivity this should register an android.widget.AbsListView.AdapterDataSetObserver within the setAdapter method of ListView (invoked from setListAdapter of ListActivity).

在通知任何改变的注册DataSetObserver对象AdapterDataSetObserver和的ListView为此requestLayout的OnChanged方法被调用。这应该(我的理解)刷新的ListView。

Upon notifying the registered DataSetObserver objects of any change the onChanged method of the AdapterDataSetObserver and therefor requestLayout of the ListView should be invoked. This should (to my understanding) refresh the ListView.

不过,在ListView不会更新与新的数据。

However, the ListView is not updated with the new data.

我意识到它已经指出,notifyDataSetChanged和(也许)notifyChanged应在一个runOnUiThread环境中运行,但似乎并没有解决这个问题。

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.

我也意识到,类似的问题上来,而与此组特定的Andr​​oid班,并不能令人满意的答案。

I also realize that similar questions came up, but not with this specific set of android classes, and with unsatisfying answers.

我缺少什么?任何了解为什么这打破以及如何解决它大大AP preciated。

Am i missing anything? Any insight into why this breaks and how to fix it is greatly appreciated.

推荐答案

适配器 registerDataSetObserver()部分接口是谁可能有兴趣知道当数据集变化的任何外部对象。 A 的ListView 应该不是真的有兴趣在这些方法......如果是 BaseAdapter 含量的变化,你叫 BaseAdapter.notifyDataSetChanged()这将告诉ListView的自我更新。

The registerDataSetObserver() part of the Adapter interface is for any external objects who might be interested to know when the data set changes. 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.

在换句话说,你只需要作以下微小的变化:

In other words you only need to make the following tiny change:

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

实际上,因为你改变现有项目的状态(而不是增加新的等),然后notifyDataSetInvalidated()会是一个更好的选择。

Actually, since you're changing the state of an existing item (rather than adding new ones etc) then notifyDataSetInvalidated() would be a better choice.

当然,你不需要任何的DataSetObserver东西,除非你其实有其他地方的其他对象需要知道这些数据。

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.

这篇关于从BaseAdapter调用notifyDataSetChanged时ListView控件不更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆