2012-11-22 51 views
1

我有一个奇怪的/独特的情况与我的ListView。这是场景:异步调用后ListView不更新

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

我提到的一切都很好,只要设备旋转,一些有趣的发展发生。

异步调用恢复正常,并为属性(数组)提供值。所以没有错......(是的,有收集数据)然后我设置ListView Adapter并打电话notifyDataSetChanged,但没有任何反应。用户界面没有更新或什么?如果我重新输入Activity,数据会再次显示?

我甚至试图在ListView上打电话invalidateViewsinvalidate - 这没有做任何事情。

请问有人能帮我解决这个问题吗? 非常感谢提前!

[更新]

我想强调的是,我正在使用C#(Xamarin),而不是Java的事实(:感叹: - 是的,我知道)。此外,我没有使用ASyncTask类,而是使用由Visual Studio生成的代理类中创建的异步方法。非常简单的,但是这是填充ListView编码 - 属性是从主持人设置

演示

哪里查看类型为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(); 
     } 
    } 

活动

活动实施TS 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(); 
        } 
       }); 
     } 
    } 

[/更新]

回答

2

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

活动:

覆盖的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); 
     } 
     ... 
    } 

也许,你看到我在前面的代码示例中做了什么?是的,我送活动主持人的新实例 - 看看在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; 
    } 
} 

上面的代码可以帮助我的演示者说创建新的活动 - 所以当它在异步调用后返回数据时,它将拥有最新最好的活动实例!

希望这会有所帮助! 亲切的问候,

1

得到它通过执行工作如下:

声明活性的一个静态变量:

private static ContactsActivity _cachedActivity = null; 

推翻了OnResume内的活动并设置变量:

protected override void OnResume() 
    { 
     base.OnResume(); 
     _cachedActivity = this; 
    } 

覆盖在活动范围内的OnCreate和设置变量:

protected override void OnCreate(Bundle bundle) 
    { 
     ... 
     _cachedActivity = this; 
     ... 
    } 

最后我改变了前面提到的财产:

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

亲切的问候,