0

Я пытаюсь выполнить асинхронную анимацию, которая не блокирует основной поток. сценарий, что я пытаюсь сделать:Неблокирующая анимация анимации пользовательского интерфейса

  • пользователь нажимает на кнопку, и через некоторое время свойство 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 ..).

Как я могу запустить анимацию async?

ответ

0

Прошу прощения за мой плохой английский.

В вопросе я удалил концевые линии анимационного сценария для навороты, но проблема была скрыта там. В моем случае проблема была в использовании Thread.Sleep.

Это замораживает основной поток пользовательского интерфейса.

Вместо этого я должен использовать задачу async. И используйте 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; 
         })); 
       })); 
     }); 
    }); 
}