繁体   English   中英

如何在 Xamarin Forms Shell 中区分启动屏幕

[英]How to differentiate StartUp screens in Xamarin Forms Shell

我有注册/登录部分以及主要内容。

主要内容有标签栏部分(向下标签),但我只想在主要部分显示这些标签。 注册/登录部分没有。 首先,在我的 App.cs 中,我需要检查用户是否存在(来自安全商店的凭据),并根据我的 api 作为答案返回的内容,我需要向用户显示正确的页面(注册时他上次停止的某个步骤,或者如果凭据正常,将即时消息重定向到带有向下选项卡的主扇区)

我按如下方式设置我的 AppShell:

    <ShellItem Route="login">
        <ShellContent ContentTemplate="{DataTemplate login:Page1}" />
        <ShellContent ContentTemplate="{DataTemplate login:Page2}" />
    </ShellItem>

    <ShellItem Route="register">

        <ShellContent ContentTemplate="{DataTemplate register:RegisterPage1}" />
        <ShellContent ContentTemplate="{DataTemplate register:RegisterPage2}" />
        <ShellContent ContentTemplate="{DataTemplate register:RegisterPage3}" />
    </ShellItem>


    <TabBar Route="main">
        <Tab Title="Activity" Icon="tab_feed.png">
            <ShellContent ContentTemplate="{DataTemplate postlogin:ActivityPage}" />
        </Tab>
        <Tab Title="Invest" Icon="tab_about.png">
            <ShellContent ContentTemplate="{DataTemplate postlogin:InvestPage}" />
        </Tab>
    </TabBar>

知道我想以某种方式告诉 AppShell 的代码隐藏,根据我的 api 响应转到特定的路由页面。 我试过类似的东西:

public AppShell()
        {
            MainThread.BeginInvokeOnMainThread(async () =>
            {
                await Shell.Current.GoToAsync("//register");
            });
            InitializeComponent();
        }

但我有空引用异常。 你有更好的架构解决方案吗?

我认为您应该将登录和注册页面与外壳分开处理。 换句话说,当应用程序启动时,检查用户是否需要登录/注册。 如果是这样,将登录和/或注册页面作为模态页面推送,覆盖 Shell 界面。 完成登录/注册后,弹出模态页面,您将进入带有选项卡的 Shell。

或者,您可以在应用启动时将Application.MainPage分配给您的登录或注册页面,然后在完成后将Application.MainPage重新分配给AppShell ,例如:

MainPage = new LoginPage();
// Authenticated!! - now open the shell
MainPage = new AppShell();

更新:虽然我没有理由确保登录/注册页面“在外壳中”,特别是因为有人说他们在显示注册/登录页面时不想要标签,但问题是开头问题中的代码是他们在 AppShell 构造函数期间调用 Shell.Current。 您可以通过添加await Task.Delay(500)来避免该错误,让 AppShell 完成构造(您可能应该先调用InitializeComponent ),例如:

public AppShell()
    {
        InitializeComponent();
        MainThread.BeginInvokeOnMainThread(async () =>
        {
            await Task.Delay(500);
            await Shell.Current.GoToAsync("//register");
        });

    }

然而,这确实违背了建议不要从构造函数启动异步方法的最佳实践。 这是关于替代方案的博客文章: https : //blog.stephencleary.com/2013/01/async-oop-2-constructors.html

例如做这样的事情:

public sealed class MyClass
{
  private MyData asyncData;
  private MyClass() { ... }

  private async Task<MyClass> InitializeAsync()
  {
    asyncData = await GetDataAsync();
    return this;
  }

  public static Task<MyClass> CreateAsync()
  {
    var ret = new MyClass();
    return ret.InitializeAsync();
  }
}

public static async Task UseMyClassAsync()
{
  MyClass instance = await MyClass.CreateAsync();
  ...
}

用以下代码替换您的代码并享受:)

InitializeComponent();
MainThread.BeginInvokeOnMainThread(async () =>
            {
                await GoToAsync("//register");
            });
        

你可以试试这个,你不需要从Shell单独login/registration 它将根据它在AppShell放置方式简单地加载。 然后通过首选项,您可以说要从头开始导航的位置。

我在我的一个项目中进行了这项工作。

AppShell.cs:

    public AppShell()
    {
        InitializeComponent();

        RegisterRoutes();

        bool mainLogin = Preferences.ContainsKey(Settings.RememberLogin);

        if (mainLogin)
        {
            _ = GoToAsync("//Main");
        }
    }

    private void RegisterRoutes()
    {
        Routing.RegisterRoute("Register", typeof(RegisterPage));
        Routing.RegisterRoute("Login", typeof(LoginPage));
    }

AppShell.xaml:

    <ShellItem Route="MainPage" Shell.FlyoutBehavior="Disabled" 
               FlyoutItemIsVisible="False" Shell.ForegroundColor="White" Shell.TitleColor="White" 
               Shell.BackgroundColor="{StaticResource Primary}">
        <ShellContent ContentTemplate="{DataTemplate local:MainPage}" />
    </ShellItem>

  <TabBar Route="Main">
        <Tab Title="Activity" Icon="tab_feed.png">
            <ShellContent ContentTemplate="{DataTemplate postlogin:ActivityPage}" />
        </Tab>
        <Tab Title="Invest" Icon="tab_about.png">
            <ShellContent ContentTemplate="{DataTemplate postlogin:InvestPage}" />
        </Tab>
    </TabBar>

主页.xaml:

  <Button Command="{Binding GoToLoginPageCommand}" />
  <Button Command="{Binding GoToRegisterPageCommand}" />

当登录正确时:

Preferences.Set(Settings.RememberLogin, true);
await Shell.Current.GoToAsync("//Main");

您将不得不使其适应您的项目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM