创建XAML Splash页面并导航到选项卡页面

时间:2018-05-09 15:52:20

标签: xamarin.forms navigation mvvm-light splash-screen

我已经使用MVVMLight并跟随this article设置了我的XF应用程序。

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

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

我已经阅读了很多文章并尝试过几件事情,而且我遇到了其中一个问题:

  1. 启动页面加载但未导航到选项卡页面。
  2. Splash页面根本不加载并导航到选项卡页面 直接
  3. This article是我遇到的最接近但我在发布信号量时似乎遇到错误:

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

    提前致谢。

1 个答案:

答案 0 :(得分:0)

行!所以我想出了导航,也不需要为信号量而烦恼。

以下步骤详细说明答案:

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

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

  3. 如果根据link使用MVVMLight,那么:

    一个。创建一个SplashViewModel.cs文件。

    湾在SplashViewModel.cs中,创建一个名为Initialize的私有异步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将成为导航堆栈中的第2页。这不应该是这种情况,因为第1页或根页应该始终是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方法在构造函数中。

  6. 我花了很多时间搞清楚这一点,所以我希望这会在需要时有所帮助。