Показывать ActivityIndicator при нажатии новой страницы для навигации
У меня возникли некоторые проблемы с реализацией такой простой функции, как показ ActivityIndicator во время загрузки страницы, это оказалось очень сложно.
Вот код, который я использую на App.xaml.cs:
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new LoginPage());
}
}
И это мой логин
public partial class LoginPage : ContentPage
{
public LoginPage()
{
InitializeComponent();
btnLogin.Clicked += BtnLogin_Clicked;
}
protected async void BtnLogin_Clicked(object sender, EventArgs e)
{
loadingView.IsVisible = true;
activityIndicator.IsRunning = true;
await Navigation.PushAsync(new SchedulePage());
loadingView.IsVisible = false;
activityIndicator.IsRunning = false;
}
}
Не вдаваясь в подробности, loadView - это представление, которое я имею в файле xaml, в котором находится мой ActivityIndicator. Моя главная проблема здесь заключается в том, что когда я вызываю Navigation.PushAsync(), анимация ActivityIndicator останавливается. Согласно тому, что я прочитал, это происходит потому, что обе операции происходят в главном потоке, поэтому одна прерывает другую.
Причина, по которой мне нужно показывать индикатор, заключается в том, что мой SchedulePage занимает много времени для рендеринга, поскольку он имеет элемент управления календаря XLabs.
Как бы вы реализовали что-то подобное?
3 ответа
Вчера я расследовал этот случай, потому что у меня есть ActivityIndicator, который не отображается, когда я активировал его перед PushAsync. Я видел здесь и stackru и все решения решения для запуска PushAsync внутри Device.BeginInvokeOnMainThread внутри Task.Run, я попробовал, но ничего не изменилось.
Затем я понял, что все, что мне нужно, - это еще одна асинхронная задача, требующая времени ActivityIndicator до запуска PushAsync. Так вот код работает в моем проекте:
public partial class MyActivities : ContentPage
{
private bool _isLoading;
public bool IsLoading //Binded to ActivityIndicator
{
get { return _isLoading; }
private set
{
_isLoading = value;
OnPropertyChanged("IsLoading");
}
}
public MyActivities()
{
BindingContext = this;
InitializeComponent();
btnNavitage.Clicked += async (s,a) =>
{
IsLoading = true;
var animateEnd = await aiControl.FadeTo(1d); //aiControl is the ActivityIndicator, animate it do the trick
try
{
await Navigation.PushAsync(new CheckInForm()); //when the code reach the PushAsync, ActivityIndicator is already running
}
finally
{
IsLoading = false;
}
}
}
}
Вы должны попробовать обернуть свою навигацию по страницам примерно так:
Device.BeginInvokeOnMainThread (async() => {
await Navigation.PushAsync(new SchedulePage());
});
Это позволяет запускать процесс и обеспечивает отзывчивость ваших элементов пользовательского интерфейса.
// Как продолжение к Джотаде
// Нет необходимости устанавливать другое свойство, просто установите IsRunning в True в XAML и выполните следующее
-- code remove for brevity
ActivityIndicator.IsVisible = true;
await Task.Delay(500);
try
{
await Navigation.PushAsync(new TransactionCalculationPage(), true);
}
finally
{
ActivityIndicator.IsVisible = false;
}