我正在尝试执行异步动画,这不会阻塞主线程。 我想要做的场景:
用户单击一个按钮,并在一段时间后查看ViewModel属性 改变其状态。
在MvxFragment视图中我订阅了OnPropertyChanged
事件,如果所需的属性已更改,我会执行动画(显示通知给
用户几秒钟。)
我很困惑,当动画正在进行时应用程序没有响应:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignore = base.OnCreateView(inflater, container, savedInstanceState);
var view = this.BindingInflate(Resource.Layout.MyView, null);
ViewModel.WeakSubscribe(PropertyChanged);
return view;
}
private void PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsSaved")
{
if (ViewModel.IsSaved)
{
ShowSavedPopup();
}
}
}
private void ShowSavedPopup()
{
var dispatcher = Mvx.Resolve<IMvxMainThreadDispatcher>();
dispatcher.RequestMainThreadAction(() =>
{
var popupView = View.FindViewById(Resource.Id.popup);
popupView.Alpha = 0.0f;
popupView.Animate()
.SetDuration(4000)
.Alpha(1f)));
});
}
我也尝试了不同的方法来运行动画异步,但没有一个工作(等待Task.Run,Activity.RunOnUiThread ..)。
如何运行动画异步?
答案 0 :(得分:0)
我为我可怜的英语道歉。
问题我删除了brewity动画场景的结束行,但问题隐藏在那里。 在我的情况下,问题是使用Thread.Sleep。
冻结了主UI线程。
我应该使用异步任务。并使用Task.Delay显示所需时间段的弹出窗口。
工作解决方案将是:
private async void ShowSavedPopup()
{
// check if animation is in progress
if (_isBusy) return;
_isBusy = true;
await Task.Factory.StartNew(() =>
{
_popupView.Post(() =>
{
_popupView.Visibility = ViewStates.Visible;
_popupView.Alpha = 0.0f;
_popupView.Animate()
.SetDuration(400)
.Alpha(1f)
.WithEndAction(new Runnable(async () =>
{
await Task.Delay(2000);
_popupView.Animate()
.SetDuration(400)
.Alpha(0.0f)
.WithEndAction(new Runnable(() => {
_popupView.Visibility = ViewStates.Gone;
isBusy = false;
}));
}));
});
});
}