Показывать 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;
        }   
Другие вопросы по тегам