将新页面推送到导航时显示ActivityIndicator

本文关键字:显示 ActivityIndicator 导航 新页面 | 更新日期: 2023-09-27 17:58:29

我在实现像加载页面时显示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;
        }
    }

在不涉及太多细节的情况下,loadingView是我在xaml文件上的一个视图,其中包含我的ActivityIndicator。我在这里的主要问题是,当我调用Navigation.PushAsync()时,ActivityIndicator的动画会暂停。根据我所读到的内容,这是因为两个操作都发生在主线程上,所以其中一个会中断另一个。

我需要显示指示器的原因是,我的SchedulePage需要很多时间来渲染,因为它有一个XLabs日历控件。

你会如何着手实现这样的东西?

将新页面推送到导航时显示ActivityIndicator

您应该尝试用这样的东西包装页面导航:

Device.BeginInvokeOnMainThread (async() => {
await Navigation.PushAsync(new SchedulePage());
});

这允许流程启动并保持UI元素的响应。

昨天我在调查这个案例,因为我有一个ActivityIndicator,当我在PushAsync之前激活它时,它不会显示。我在这里看到了stackoverflow和所有解决方案都指向在设备内运行PushAsync。在任务内启动OnMainThread。运行时,我尝试过,但没有改变。

然后我意识到我所需要的只是另一个异步任务,它在PushAsync运行之前给ActivityIndicator时间。下面是我项目中的代码:

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;
            }
        }
    }
}

//作为jotade
的后续//无需设置其他属性,只需在XAML中将IsRunning设置为True并执行以下即可

        -- code remove for brevity
        ActivityIndicator.IsVisible = true;
        await Task.Delay(500); 
        try
        {
            await Navigation.PushAsync(new TransactionCalculationPage(), true);
        }
        finally
        {
            ActivityIndicator.IsVisible = false;
        }