我的ListView
有一种奇怪/独特的情况。这是场景:
我正在使用MVP设计模式。当Activity
启动时,它会引发一个事件以通知演示者从Web服务获取一些数据。 Web服务调用是异步调用。引发Web服务Completed
事件后,我会将结果推送到位于View
/ Activity
内的属性(类型为Array)中。
我提到的一切都很好,但一旦设备旋转,就会发生一些有趣的发展。
异步调用恢复正常,并为属性(Array)提供值。所以没有错误...(是的,集合中有数据)我然后设置ListView Adapter
并调用notifyDataSetChanged
,但没有任何反应。用户界面没有更新或什么?如果我重新输入Activity
数据再次可见??
我甚至尝试在invalidateViews
上调用invalidate
和ListView
- 这没有做任何事情。
有人可以帮我解决这个问题吗? 非常感谢提前!
[更新]
我想强调的是,我正在使用C#(Xamarin)而不是Java(:叹息: - 是的,我知道)。此外,我没有使用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();
}
}
活动
该活动实现了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();
}
});
}
}
[/更新]
答案 0 :(得分: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 :(得分: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();
}
});
}
}
亲切的问候,