Search code examples
c#mauiblazor-hybrid

MAUI Blazor Hybrid background colors on load


I have a .NET 7 MAUI app that has a dark background (not only in dark mode). We require users to log or pin in to use the app and the login/pin entry page has a dark background. On success, we navigate them to the Main Landing Page. The main landing page is a content page with the BlazorWebView.

MainLandingPage.xaml

 <BlazorWebView HostPage="wwwroot/index.html">
     <BlazorWebView.RootComponents>
         <RootComponent Selector="#menu-bar" ComponentType="{x:Type components:MenuBar}" />
         <RootComponent Selector="#app" ComponentType="{x:Type main:FormGridContainer}" x:Name="HomePageComponent" />
     </BlazorWebView.RootComponents>
 </BlazorWebView>

index.html defined as

<body>
    <div class="status-bar-safe-area"></div>
    <div id="menu-bar">Menu Bar Here</div>
    <div id="app">Loading...</div>
    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>
    <script src="_framework/blazor.webview.js" autostart="false"></script>
</body>

Everything loads as expected. However, there is a "flash" of white as the BlazorWebView loads the components. First an all white screen shows while the index.html is loaded. After the index.html loads, you see this as expected: WhiteScreen

After the blazor components load, the page looks like this MainPageLayout

Ideally, I would like a way to show a busy indicator on a dark background while the Blazor components load. Once loaded, show the BlazorWebView and hide indicator. I have tried setting IsVisible in the BlazorWebViewInitialized (not late enough in lifecycle), adding a style to the body of the index.html (too late in lifecycle), IsVisible properties with an ObservableProperty backing value (no BlazorWebView is ever shown, busy indicator disappears), setting background color of the various MainLandingPage.xaml elements (just delays or shortens white flash) and OnAfterRender of the main blazor component (calls a function on MainLandingPage.xaml.cs, setting a property, via a callback in a viewmodel). The two outcomes for all scenarios are either the correct color background with no web view or the flash of white.

The closest I have come is when I set the background color in the index.html and the MainPageLayout. The result is that the white flash is not a long.

Is this possible in MAUI?

UPDATE 1:

MainLandingPage.xaml with ActivityIndicator

 <ContentPage.Resources>
     <toolkit:InvertedBoolConverter x:Key="InvertedBoolConverter" />
 </ContentPage.Resources>
 <ScrollView Orientation="Horizontal" BackgroundColor="#F3F5F9">
     <ActivityIndicator IsVisible="{Binding IsBusy}" IsRunning="True" />
     <BlazorWebView HostPage="wwwroot/index.html" IsVisible="{Binding IsBusy, Converter={StaticResource InvertedBoolConverter}}">
         <BlazorWebView.RootComponents>
             <RootComponent Selector="#menu-bar" ComponentType="{x:Type components:MenuBar}" />
             <RootComponent Selector="#app" ComponentType="{x:Type main:FormGridContainer}" x:Name="HomePageComponent" />
         </BlazorWebView.RootComponents>
    </BlazorWebView>
</ScrollView>

In the MenuBar Blazor component, there is nothing fancy. A logo, a couple of buttons and a bootstrap dropdown.

In the FormGridContainer component, there is quite a bit of stuff there. It has a left and right-side drawer with the main content in between. The left side drawer has a treeview, and there are only 5 things in the treeview for now. The main content, we get a list of forms that have been completed, but on initial install/login, this is blank, and the right drawer is empty. We do quite a bit of work getting all the form data in the FormGridContainerViewModel. We are not using any 3rd party blazor components. Just the out of the box stuff.


Solution

  • Posed the same question here. Bruce's answer lead me down the right path. Since I am using the BlazorWebView in my xaml I ended up using the following code in my xaml.cs file:

    BlazorWebViewHandler.BlazorWebViewMapper.AppendToMapping("MyBlazorCustomization", (handler, view) =>  {
        #if IOS
            handler.PlatformView.Opaque = false;
            handler.PlatformView.BackgroundColor = UIKit.UIColor.Clear;
        #elif WINDOWS
            handler.PlatformView.Opacity = 0;
            handler.PlatformView.DefaultBackgroundColor = new Windows.UI.Color() { A = 0, R = 0, G = 0, B = 0 };
        #endif
        });