android - 异步调用后 ListView 未更新

标签 android

我的 ListView 有一个奇怪/独特的情况。这是场景:

我正在使用 MVP 设计模式。当 Activity 启动时,它会引发一个事件来通知演示者从 Web 服务中获取一些数据。 Web 服务调用是异步调用。引发 Web 服务 Completed 事件后,我获取结果并将其推送到驻留在我的 View/Activity 中的属性(数组类型)中

我提到的一切都很好,但是一旦设备旋转,就会发生一些有趣的变化。

异步调用恢复正常,并为属性 (Array) 提供一个值。所以没有错...(是的,集合中有数据)然后我设置了 ListView Adapter 并调用了 notifyDataSetChanged,但没有任何反应。用户界面没有更新或什么??如果我重新进入 Activity,数据将再次可见 ??

我什至尝试在 ListView 上调用 invalidateViewsinvalidate - 这没有做任何事情。

有人可以帮我解决这个问题吗? 非常感谢!

[更新]

我想强调一个事实,我使用的是 C# (Xamarin) 而不是 Java(:sigh: - 是的,我知道)。此外,我没有使用 ASyncTask 类,而是使用在 Visual Studio 生成的代理类中创建的异步方法。非常简单,但这是填充 ListView 的代码 - 该属性是从演示者设置的

演示者

View 的类型是 IContactsView

    protected override void OnCollectData(System.Collections.IEnumerable data, Type typeOfData)
    {
        if (data != null && typeOfData != null && typeOfData.Equals(typeof(UserContact)))
        {
            this.View.UserInformationCollection = data.Cast<UserContact>().ToArray();
        }
    }

Activity

Activity 实现了 IContactsView

    public UserContact[] UserInformationCollection
    {
        get
        {
            return this._userInformationCollection;
        }
        set 
        {
            this.RunOnUiThread(() =>
                {
                    this._userInformationCollection = value;                        
                    ListView listview = this.FindViewById<ListView>(Resource.Id.userLV);
                    if (listview != null)
                    {                           
                        UserContact[] subsidiesList = this.GetIndexedContacts(this._userInformationCollection);
                        listview.Adapter = new ContactsAdapter(this, subsidiesList.ToList());
                        ((ContactsAdapter)listview.Adapter).NotifyDataSetChanged();
                    }
                });
        }
    }

[/更新]

最佳答案

找到了更好的解决方案!所以请忽略static variable的想法!

Activity :

覆盖 OnRetainNonConfigurationInstance 并返回演示者

    public override Java.Lang.Object OnRetainNonConfigurationInstance()
    {
        return this._presenter;
    }

OnCreate 中检查 LastNonConfigurationInstance 并获取演示者 - 如果它不为空:

    protected override void OnCreate(Bundle bundle)
    {
        ...
        if (this.LastNonConfigurationInstance != null)
        {
            this._presenter = this.LastNonConfigurationInstance as ContactsPresenter;
            this._presenter.RefreshView(this);
        }
        else
        {
            // create a new presenter
            this._presenter = new ContactsPresenter(this);
        }
        ...
    }

也许,您看到了我在前面的代码示例中所做的事情?是的,我将 Activity 的新实例发送给演示者 - 查看 RefreshView

主持人:

所以在我的基本演示器中,我有以下方法:

public class Presenter<T> : Java.Lang.Object, IPresenter where T : IView
{
    /// <param name="view">The view.</param>
    public void RefreshView(T view)
    {
        this.View = view;
    }
}

上面的代码帮助我的演示者创建新 Activity - 因此当它在异步调用后返回数据时,它将拥有最新和最好的 Activity 实例!

希望对您有所帮助! 亲切的问候,

关于android - 异步调用后 ListView 未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13507758/

相关文章:

java - 如何在 Java 中解析日期?日期格式有些困惑

android - 是否可以开发一个时钟并使其始终显示在 android 设备的屏幕上?

android - 改变某部分字符串的edittext的输入类型

android - Android Studio 更新后无法将 R 解析为变量

android - 如何在Android Studio 2.0中激活Instant Run

android - 在 React Native 中加载 Android 图像

java - 在 SaveInstanceState 上保存和恢复 ArrayDeque

java - ImageView 为空

android - 带图标的 AlertDialog MultiChoiceItems

java - 如何在android中的sqlite数据库中插入日期选择器和时间选择器