在 dotNET MAUI 中使用 Shell 导航,确保页面转换始终具有动画效果并在不同设备上尽可能流畅地执行的最佳(最可靠)方法是什么?
我确实找到了最简单的解决方案,但我想知道是否有更好的方法。我目前的做法似乎不太可靠,尤其是在不同的(较慢和较快)设备上。这真的是最好/最可接受的方式吗?
实际问题:
我注意到我的一些页面需要加载的数据稍微多一些。虽然在我看来这仍然是一个相当可以接受的数量,但导航动画没有显示,因为加载数据会导致它滞后。请注意,在我的例子中,由于
Appearing
接口,我必须在 ViewModel 的 IQueryAttributable
事件中加载数据。属性是在构造函数之后但在填充视图的出现事件之前通过查询参数设置的。我正在使用 MAUI Community Toolkit 将页面出现事件转换为命令。
我目前的解决方案:
我正在使用 Shell
await Shell.Current.GoToAsync($"{nameof(PageName)}", true, Params);
导航到一个页面,这是我将拥有的目标页面的一个非常原始/简单的示例:
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:m="clr-namespace:MauiApp1.Models"
xmlns:tk="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:vm="clr-namespace:MauiApp1.ViewModels"
x:DataType="vm:PageNameViewModel">
<ContentPage.Behaviors>
<tk:EventToCommandBehavior Command="{Binding OnAppearingCommand}" EventName="Appearing"/>
</ContentPage.Behaviors>
<StackLayout>
<CollectionView ItemsSource="{Binding Items}">
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="m:Item">
<VerticalStackLayout>
<!-- Using item data here -->
</VerticalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
</ContentPage>
视图模型:
我基本上是先延迟
OnAppearing()
中的所有内容,然后再实际填充页面:
public class PageNameViewModel : BaseViewModel, IQueryAttributable
{
private List<Item> items { get; set; } = new();
public ObservableCollection<Item> Items { get; set; } = new();
public Command OnAppearingCommand { get; private set; }
public PageNameViewModel()
{
OnAppearingCommand = new Command(OnAppearing);
}
public void ApplyQueryAttributes(IDictionary<string, object> Params)
{
items = Params["Items"] as items;
}
private async void OnAppearing()
{
// Delay here to wait for page animation, before populating the page:
await Task.Delay(500);
foreach (var item in items)
{
Items.Add(item);
}
}
}
我认为这可能不太可靠,因为在较旧且较慢的设备上,延迟时间可能太短。在高端设备上,延迟时间甚至可能变得明显且烦人。
这是可以接受的做法吗?
如何将您的
Delay
分布在所有项目上,以便一些项目在显示页面时开始,而其余项目将在页面完成时显示?
private async void OnAppearing()
{
foreach (var item in items)
{
Items.Add(item);
await Task.Delay(10);
}
}