xamarin.forms - 创建 XAML 启动页面并导航到选项卡式页面
问题描述
我已经使用 MVVMLight 并按照这篇文章设置了我的 XF 应用程序。
我现在想介绍一个 XAML Splash 页面,通过将其分配给 App.xaml.cs 中的 MainPage 属性来在启动时加载它。加载后,在启动页面中,我想做一些异步任务来初始化应用程序,即从 API 获取初始数据等。完成后,我想导航到 MainTabbed 页面。
我还没有编写初始化逻辑,所以我使用 Thread.Sleep 来模拟它。
我已经阅读了很多文章并尝试了一些事情,但我陷入了遇到以下任何一个问题的地步:
- 启动页面加载但随后不导航到选项卡式页面。
- 启动页面根本不加载并直接导航到选项卡页面。
这篇文章是我遇到的最接近的文章,但我在释放信号量时似乎遇到了错误:
05-09 19:22:12.471 I/MonoDroid(14342): System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Threading.SemaphoreFullException: Adding the specified count to the semaphore would cause it to exceed its maximum count.
05-09 19:22:12.471 I/MonoDroid(14342): at System.Threading.SemaphoreSlim.Release (System.Int32 releaseCount) [0x0004c] in <fcbf47a04b2e4d90beafbae627e1fca4>:0
05-09 19:22:12.471 I/MonoDroid(14342): at System.Threading.SemaphoreSlim.Release () [0x00000] in <fcbf47a04b2e4d90beafbae627e1fca4>:0
感谢有关上述内容的任何建议,或者如何使用 xaml 实现启动页面(如果这在概念上甚至有意义的话),因为大多数文章都在本机项目中使用本机实现或图像。
提前致谢。
解决方案
好的!!所以我弄清楚了导航,也不需要为信号量而烦恼。
以下步骤详细说明了答案:
在服务类或单独的类中创建长时间运行的方法,如下所示
public async Task LongRunning() { //Write code to download data from an API or something. }
创建一个“SplashPage.xaml”文件并将其分配给 App.cs 中的 MainPage 属性。这会将 SplashPage 设置为 NavigationStack 中的第一个或根页面。
如果按照链接使用 MVVMLight,则:
一个。创建一个 SplashViewModel.cs 文件。
湾。在 SplashViewModel.cs 中,创建一个名为 Initialize 的私有 async void 方法,该方法具有以下代码:
private async void Initialize() { //Need to await till the task is done. Very important await yourService.LongRunning(); //Only after task is done should it navigate to next page NavigationService.NavigateTo(nameof(MainTabbedPage)); }
导航到 MainTabbedPage 后,MainTabbedPage 将成为导航堆栈中的第二个页面。这不应该是这种情况,因为第一个或根页面应该始终是 MainTabbedPage。此外,不需要再次导航到 SplashPage。为了解决这个问题,请将以下代码放在 MainTabbedPage 的 OnAppearing 事件中。
protected override void OnAppearing() { base.OnAppearing(); var splashPage = Navigation.NavigationStack[0]; Navigation.RemovePage(splashPage); }
这将从导航堆栈中删除 SplashPage 并将 MainTabbedPage 设置为根页面,然后再导航到任何其他页面。
如果您不使用 MVVMLight 而是直接在代码隐藏或其他东西中编写代码,则可以将步骤 3b 中的代码放在代码隐藏中 - SplashPage.xaml.cs 并且可以在构造函数中调用 Initialize 方法。
我花了很多时间来解决这个问题,所以我希望这在需要时有所帮助。
推荐阅读
- c++ - 我如何使用 unordered_map .find() 引发读取访问冲突?
- android - 找不到错误 Android 项目。你确定这是一个 React Native 项目吗?
- three.js - 来自三个.js 中导入的 glTF 的顶点颜色
- flutter - Flutter:找不到FutureBuilder上面的Provider
- r - 重新启动中断的 Promise 评估是否有问题?
- android - 无法在不重新加载的情况下使用 Flutter_WebRTC 包
- android - 无法构建 Android App Bundle,因为它使用了保留的文件或目录名称“res”
- sql-server - 实体框架:如何使用多边形类型进行嵌套的“选择不同的 .. where in”
- mysql - Mariadb - 如何通过查询删除历史记录?
- javascript - JavaScript .sort() 和 .indexOf() 方法出错