locked
Getting a white screen while navigating. RRS feed

  • Question

  • User9811 posted

    Hi.

    I am building a Xamarin.Forms app using PRISM and I am getting the weirdest behavior. I am pretty sure that it started right after I updated PRISM when the made their IInitialize breaking change.

    Here is the flow of my app. The first screen is the Login page and I am navigating to it in my OnInitialized method in App.xaml.cs

    await NavigationService.NavigateAsync("NavigationPage/MainPage");

    Once the user is logged in I am using the following line to navigate to the "home" page:

    await NavigationService.NavigateAsync("/MainMasterPage/NavigationPage/PlayersHomePage");

    This is where I get the white screen for a second and then the tabbed page loads up OK. I notices that if I remove the Navigation page the white screen does not show up, but I cant do without it.

    the PlayersHomePage is a TabbedPage with 3 tabs:

    xaml <TabbedPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms" xmlns:views="clr-namespace:FplMatchdayLive.Views" prism:ViewModelLocator.AutowireViewModel="True" Title="{Binding Title}" x:Class="xxx.Views.PlayersHomePage"> <TabbedPage.Children> <views:TeamPage></views:TeamPage> <views:LeaguesPage></views:LeaguesPage> <views:FixturesPage></views:FixturesPage> </TabbedPage.Children> </TabbedPage>

    in the PlayersHomePage code behinde I am using IInitalize to initialize all the tabs:

    public partial class PlayersHomePage : TabbedPage, IInitialize { public PlayersHomePage() { InitializeComponent(); } public void Initialize(INavigationParameters parameters) { if (parameters.GetNavigationMode() == NavigationMode.New) { // Prism always raises OnNavigatedTo on 1st tabbed page so this prevents the first tab being initialised twice if (Children.Count == 1) { return; } for (var pageIndex = 1; pageIndex < Children.Count; pageIndex++) { var page = Children[pageIndex]; (page?.BindingContext as INavigationAware)?.OnNavigatedTo(parameters); } } } }

    I tried removing all the tabs from the TabbedPage thinking its the initialization that is causing this but it did not help.

    Any ideas as to how to solve it?

    Tuesday, October 29, 2019 2:12 PM

Answers

  • User76049 posted

    Something is thread blocking, comment out any navigation events/ Initialise etc in each viewmodel and see bring them back one by one and see where the issue is happening.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Tuesday, October 29, 2019 3:50 PM

All replies

  • User76049 posted

    Your overriding Initialise which is non async and will thread block, I do the same in several apps but override OnNavigatedTo so essentially this will happen OnAppearing and shouldn't have the UI thread while navigating

    ``` public partial class MyTabbedPage: TabbedPage, INavigatedAware { public MyTabbedPage() { InitializeComponent(); }

        public void OnNavigatedFrom(INavigationParameters parameters)
        {
            // Not used
        }
    
        public void OnNavigatedTo(INavigationParameters parameters)
        {
            if (parameters.GetNavigationMode() == NavigationMode.New)
            {
                // Prism always raises OnNavigatedTo on 1st tabbed page so this prevents the first tab being initialised twice
                if (Children.Count == 1)
                {
                    return;
                }
                for (var pageIndex = 1; pageIndex < Children.Count; pageIndex++)
                {
                    var page = Children[pageIndex];
                    (page?.BindingContext as INavigatedAware)?.OnNavigatedTo(parameters);
                }
            }
        }
    

    ```

    Tuesday, October 29, 2019 3:25 PM
  • User9811 posted

    @NMackay said: Your overriding Initialise which is non async and will thread block, I do the same in several apps but override OnNavigatedTo so essentially this will happen OnAppearing and shouldn't have the UI thread while navigating

    Changed my Tabbed page to look like your example:

    ``` public partial class PlayersHomePage : TabbedPage, INavigatedAware { public PlayersHomePage() { InitializeComponent(); }

        public void OnNavigatedFrom(INavigationParameters parameters)
        {
    
        }
    
        public void OnNavigatedTo(INavigationParameters parameters)
        {
            if (parameters.GetNavigationMode() == NavigationMode.New)
            {
                // Prism always raises OnNavigatedTo on 1st tabbed page so this prevents the first tab being initialised twice
                if (Children.Count == 1)
                {
                    return;
                }
                for (var pageIndex = 1; pageIndex < Children.Count; pageIndex++)
                {
                    var page = Children[pageIndex];
                    (page?.BindingContext as INavigatedAware)?.OnNavigatedTo(parameters);
                }
            }
        }
    }
    

    ```

    Still getting the same result. I debugged it and the OnNavigatedTo method finishes before the white screen appears.

    Tuesday, October 29, 2019 3:47 PM
  • User76049 posted

    Something is thread blocking, comment out any navigation events/ Initialise etc in each viewmodel and see bring them back one by one and see where the issue is happening.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Tuesday, October 29, 2019 3:50 PM
  • User9811 posted

    @NMackay said: Something is thread blocking, comment out any navigation events/ Initialise etc in each viewmodel and see bring them back one by one and see where the issue is happening.

    Ok. So I removed the tabs and left a single one: <?xml version="1.0" encoding="utf-8" ?> <TabbedPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms" xmlns:views="clr-namespace:FplMatchdayLive.Views" prism:ViewModelLocator.AutowireViewModel="True" Title="{Binding Title}" x:Class="FplMatchdayLive.Views.PlayersHomePage"> <TabbedPage.Children> <!--<views:TeamPage></views:TeamPage> <views:LeaguesPage></views:LeaguesPage>--> <views:FixturesPage></views:FixturesPage> </TabbedPage.Children> </TabbedPage>

    the initialization of that tab is also commented: public override async void OnNavigatedTo(INavigationParameters parameters) { base.OnNavigatedTo(parameters); //await Task.Run(() => LoadFixtures()); }

    I also commented out all the Xaml code from the fixturepage.xaml page

    Still getting that white screen it's duration is shorter though.

    Tuesday, October 29, 2019 4:13 PM
  • User380234 posted

    public override async void OnNavigatedTo(INavigationParameters parameters) { base.OnNavigatedTo(parameters); //await Task.Run(() => LoadFixtures()); }

    please try to not use async void. this is no good practice.

    here is a nice blog about how to handle it instead (and why.). (so i as a non native speaker doesnt need to edit my explaination a lot due to spelling and or grammar mistakes ;) )

    https://johnthiriet.com/removing-async-void/#

    Wednesday, October 30, 2019 6:10 AM
  • User76049 posted

    General Prism guidance is it is okay on event handlers, otherwise 100% agree, it should be avoided.

    Also if you want to run of the UI thread you could do await LoadFixtures().ConfigureAwait(false)

    As long as the navigation to this page was called in a similar manner await Navigation.NavigateAsync("PlayersHomePage", null, false, false).ConfigureAwait(false) it runs faster, also disabling the page transition animation improves the load time. Obviously any binding in LoadPlayers whould have to be pushed to the UI thread with BeginInvokeOnMainThread but it will run faster.

    This question is impossible to answer as we're seeing a tiny part of the puzzle.

    Wednesday, October 30, 2019 9:18 AM
  • User9811 posted

    @NMackay I seems that the Navigation page is responsible for all the issues. If I remove it and just do

    await NavigationService.NavigateAsync("/MainMasterPage/PlayersHomePage");

    I don`t get the white screen.

    how can I disable the transition animations?

    Wednesday, October 30, 2019 10:38 AM
  • User76049 posted

    await NavigationService.NavigateAsync("/MainMasterPage/PlayersHomePage", animated:false);

    Wednesday, October 30, 2019 10:47 AM
  • User9811 posted

    @NMackay said: Something is thread blocking, comment out any navigation events/ Initialise etc in each viewmodel and see bring them back one by one and see where the issue is happening.

    It was indeed a blocking issue. Thanks for the help!

    Thursday, October 31, 2019 6:23 PM
  • User76049 posted

    @Balue

    Remember to mark as an answer what helped you for the benefit of others.

    Friday, November 1, 2019 9:10 AM
  • User392627 posted

    Hello @Balue @NMackay and @BrianLagunas

    Same issue is for me too on Android.

    I have a login page. I am navigating to login page from App.cs code as below

    await NavigationService.NavigateAsync("/NavigationPage/LoginPage");
    

    After user logined to app, I am navigating to Master Detail Page as below

     await NavigationService.NavigateAsync("/MasterMenuPage/NavigationPage/HomePage", animated: true, parameters: new NavigationParameters
                         {
                             { "PageKey", "home" }
                         }); 
    

    Container Registery code as below

                containerRegistry.RegisterPopupNavigationService();
    
    
                containerRegistry.RegisterForNavigation<NavigationPage>(); //> that is virtual
    
                containerRegistry.RegisterForNavigation<HomePage, HomePageViewModel>();
                containerRegistry.RegisterForNavigation<MasterMenuPage, MasterMenuPageViewModel>(); //> this is master detail page
                containerRegistry.RegisterForNavigation<SupportPage, SupportPageViewModel>();
                containerRegistry.RegisterForNavigation<CallMePage, CallMePageViewModel>();
                containerRegistry.RegisterForNavigation<PrivacyPolicyPage, PrivacyPolicyPageViewModel>();
                containerRegistry.RegisterForNavigation<ContactPage, ContactPageViewModel>();
                containerRegistry.RegisterForNavigation<PolicyDetailPage, PolicyDetailPageViewModel>();
                containerRegistry.RegisterForNavigation<PolicyPaymentPage, PolicyPaymentPageViewModel>();
                containerRegistry.RegisterForNavigation<SettingsPage, SettingsPageViewModel>();
                containerRegistry.RegisterForNavigation<ProfilePhotoEditPopupPage, ProfilePhotoEditPopupPageViewModel>();
                containerRegistry.RegisterForNavigation<CustomActionSheetPopupPage, CustomActionSheetPopupPageViewModel>();
                containerRegistry.RegisterForNavigation<NotificationsPage, NotificationsPageViewModel>();
                containerRegistry.RegisterForNavigation<LoginPage, LoginPageViewModel>();
    

    MasterMenuPageViewModel.cs code as below

     public async override void Initialize(INavigationParameters parameters)
            {
                base.Initialize(parameters);
    
    
                         MasterMenuItems = new List<MasterMenuItemModel>()
                {
                        new MasterMenuItemModel()
                        {
                            Action = "NavigationPage/HomePage",
    
                        },
                        new MasterMenuItemModel()
                        {
                            Action = "NavigationPage/ContactPage",
                        }
    }
    

    Otherwise I am getting flicker when drawer menu close after navigation. I did not get good and wide app sample about MDP by created Prism Form.

    Please tell me how can I achieve this issue?

    Thursday, February 6, 2020 2:11 PM