webviewmaui

Blank space is showing after webview when loading new content in MAUI


I want to create a UI with a Label(title), image(saint image) and a webview(to show HTMl content). When scroll I want to scroll the entire item, not the webview contents only. After all these I need a section to show the audio player with previous, next and play options. So I created a UI like below:

<!-- Android view -->
<Frame 
    Padding="5"
    CornerRadius="20"
    Margin="0,10,0,0" 
    Grid.Row="1" 
    x:Name="android_webview_frame" 
    BackgroundColor="#0091DA"
    IsVisible="False">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <ScrollView
            x:Name="android_scroll_view"
            Grid.Row="0"
            Orientation="Vertical"
            VerticalOptions="FillAndExpand">

            <VerticalStackLayout
                Grid.Row="0"
                Padding="5"
                Spacing="10"
                VerticalOptions="FillAndExpand"
                BackgroundColor="#0091DA">

                <Label
                    <!-- Title label -->
                </Label>

                <!-- Saint image -->
                <Grid 
                    IsVisible="False"
                    x:Name="image_layout">
                    <!-- Saint Image with name on top of saint-->
                    
                </Grid>

                <!-- Main content -->
                <WebView 
                    x:Name="android_webview"
                    BackgroundColor="#0091DA"
                    HorizontalOptions="FillAndExpand"
                    VerticalOptions="FillAndExpand">
                </WebView>
            </VerticalStackLayout>
        </ScrollView>

        <!-- Audio border -->
        <Border
            x:Name="android_audio_border"
            Grid.Row="1"
            BackgroundColor="#014F78"
            StrokeThickness="0"
            Padding="0"
            Margin="15"
            HorizontalOptions="FillAndExpand"
            VerticalOptions="EndAndExpand">
            <Border.StrokeShape>
                <RoundRectangle CornerRadius="30"/>
            </Border.StrokeShape>
        </Border>
    </Grid>
</Frame>

Expected UI:

Expected UI

Everything is working as expected when loading content initially. My problem is When loading a different day's data, there is blank space on the bottom of the webview.

Below is the logic to show content on webview: I set a custom font and white text color for the webview contents.

string description = Details.description;
// Define custom CSS to set font and text color
string htmlContent = $@"
    <html>
    <head>
        <meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
        <style>
            @font-face {{
                font-family: 'Poppins';
                src: url('file:///android_asset/fonts/Poppins-Regular.ttf'); /* For Android */
            }}
            body {{
                background-color: #0091DA; /* Match WebView background */
                color: white; /* Set text color */
                font-family: 'Poppins', sans-serif;
                padding: 10px;
                font-size: 20px; /* Increase font size */
                line-height: 1.6; /* Improve readability */
            }}
            h4, h5, p {{
                color: white;
            }}
        </style>
    </head>
    <body>
        {description}
    </body>
    </html>";

var htmlSource = new HtmlWebViewSource();
htmlSource.Html = htmlContent;
android_webview.Source = htmlSource;

Please watch this video for a clear understanding.

I try adding a Navigated event for webview but when adding that the content is not visible on the UI. Please suggest a solution to remove the empty space after webview when loading new data.


Solution

  • You may try using Handler to customize the WebView. You may refer to Customize controls with handlers.

    And implement it in code behind,

        public DailySaintPage()
        {
            InitializeComponent();
            ModifyWebView();
            ...
            CallDailySaint(data);
        }
    
    
        void ModifyWebView()
        {
            Microsoft.Maui.Handlers.WebViewHandler.Mapper.AppendToMapping("MyCustomization", (handler, view) =>
            {
    #if ANDROID
                if (handler.PlatformView is global::Android.Webkit.WebView platformWebView)
                {
                    platformWebView.SetWebViewClient(new CustomWebViewClient(this.android_webview));
                }
    #endif
            });
        }
    

    And here is the code for CustomWebViewClient class,

    #if ANDROID
    public class CustomWebViewClient : WebViewClient
    {
    
        Microsoft.Maui.Controls.WebView mywebview;
        public CustomWebViewClient(Microsoft.Maui.Controls.WebView webView)
        {
            
            mywebview = webView;
        }
    
        public async override void OnPageFinished(Android.Webkit.WebView view, string url)
        {
            mywebview.HeightRequest = 0;
            await Task.Delay(500); // Allow time for content to load
    
            string js = "document.body.scrollHeight";
            var height = await mywebview.EvaluateJavaScriptAsync(js);
    
            if (double.TryParse(height, out double newHeight) && newHeight > 0)
            {
                mywebview.HeightRequest = newHeight;  // Set WebView height dynamically
            }
    
            base.OnPageFinished(view, url);
    
    
        }
    
    }
    #endif
    

    And you don't need custom renderer any more.

    Hope it helps!