将新页面推送到导航时显示 ActivityIndicator
Show ActivityIndicator when pushing new page to navigation
我在实现像加载页面时显示 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 日历控件。
你会如何实施这样的事情?
您应该尝试将页面导航包装成这样:
Device.BeginInvokeOnMainThread (async() => {
await Navigation.PushAsync(new SchedulePage());
});
这允许进程启动并使您的 UI 元素保持响应。
昨天我正在调查这个案例,因为我有一个 ActivityIndicator 在 PushAsync 之前激活它时不显示。我在这里看到了 Whosebug,所有解决方案都指向 运行 Device.BeginInvokeOnMainThread 内的 PushAsync Task.Run,我试过了,但没有任何变化。
然后我意识到我所需要的只是另一个异步任务,它在 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;
}
我在实现像加载页面时显示 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 日历控件。
你会如何实施这样的事情?
您应该尝试将页面导航包装成这样:
Device.BeginInvokeOnMainThread (async() => {
await Navigation.PushAsync(new SchedulePage());
});
这允许进程启动并使您的 UI 元素保持响应。
昨天我正在调查这个案例,因为我有一个 ActivityIndicator 在 PushAsync 之前激活它时不显示。我在这里看到了 Whosebug,所有解决方案都指向 运行 Device.BeginInvokeOnMainThread 内的 PushAsync Task.Run,我试过了,但没有任何变化。
然后我意识到我所需要的只是另一个异步任务,它在 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;
}