首页 > 解决方案 > 创建 XAML 启动页面并导航到选项卡式页面

问题描述

我已经使用 MVVMLight 并按照这篇文章设置了我的 XF 应用程序。

我现在想介绍一个 XAML Splash 页面,通过将其分配给 App.xaml.cs 中的 MainPage 属性来在启动时加载它。加载后,在启动页面中,我想做一些异步任务来初始化应用程序,即从 API 获取初始数据等。完成后,我想导航到 MainTabbed 页面。

我还没有编写初始化逻辑,所以我使用 Thread.Sleep 来模拟它。

我已经阅读了很多文章并尝试了一些事情,但我陷入了遇到以下任何一个问题的地步:

  1. 启动页面加载但随后不导航到选项卡式页面。
  2. 启动页面根本不加载并直接导航到选项卡页面。

这篇文章是我遇到的最接近的文章,但我在释放信号量时似乎遇到了错误:

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 实现启动页面(如果这在概念上甚至有意义的话),因为大多数文章都在本机项目中使用本机实现或图像。

提前致谢。

标签: xamarin.formsnavigationmvvm-lightsplash-screen

解决方案


好的!!所以我弄清楚了导航,也不需要为信号量而烦恼。

以下步骤详细说明了答案:

  1. 在服务类或单独的类中创建长时间运行的方法,如下所示

    public async Task LongRunning()
    {
        //Write code to download data from an API or something.
    }
    
  2. 创建一个“SplashPage.xaml”文件并将其分配给 App.cs 中的 MainPage 属性。这会将 SplashPage 设置为 NavigationStack 中的第一个或根页面。

  3. 如果按照链接使用 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));
    }
    
  4. 导航到 MainTabbedPage 后,MainTabbedPage 将成为导航堆栈中的第二个页面。这不应该是这种情况,因为第一个或根页面应该始终是 MainTabbedPage。此外,不需要再次导航到 SplashPage。为了解决这个问题,请将以下代码放在 MainTabbedPage 的 OnAppearing 事件中。

    protected override void OnAppearing()
    {
        base.OnAppearing();
        var splashPage = Navigation.NavigationStack[0];
        Navigation.RemovePage(splashPage);
    }
    

    这将从导航堆栈中删除 SplashPage 并将 MainTabbedPage 设置为根页面,然后再导航到任何其他页面。

  5. 如果您不使用 MVVMLight 而是直接在代码隐藏或其他东西中编写代码,则可以将步骤 3b 中的代码放在代码隐藏中 - SplashPage.xaml.cs 并且可以在构造函数中调用 Initialize 方法。

我花了很多时间来解决这个问题,所以我希望这在需要时有所帮助。


推荐阅读