.NET MAUI安卓:ScrollView内自定义WebView内容不可见问题解决
解决.NET MAUI安卓中ScrollView嵌套WebView不显示内容的问题
核心原因
安卓平台上,WebView与ScrollView嵌套时,WebView无法自动计算自身内容高度,导致布局高度被压缩为0,从而无法显示内容。移除ScrollView后,WebView能获取父容器的正确布局约束,因此可以正常显示。
解决方案
方案1:调整XAML布局,为WebView添加高度约束
修改Grid的行定义,将WebView所在行的高度设置为Auto,同时给WebView指定HeightRequest(可先设固定值测试,后续再动态绑定内容高度):
<Frame Margin="10,0,10,0" x:Name="android_uwp_layout" IsVisible="False" Padding="5" CornerRadius="20" Grid.Row="1"> <ScrollView Orientation="Vertical" VerticalOptions="FillAndExpand"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <!-- 改为Auto适配WebView内容高度 --> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <!-- Background Image --> <Image Aspect="Fill" HorizontalOptions="FillAndExpand" Grid.Row="0" Source="ic_daily_reading_new_bg_xx.png"/> <!-- WebView --> <local:DailyReadingAndroidWebView x:Name="mywebview" Grid.Row="0" BackgroundColor="Transparent" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" HeightRequest="800"/> <!-- 临时固定高度,后续可动态调整 --> <!-- Other UI Elements --> </Grid> </ScrollView>
方案2:自定义渲染器中动态计算WebView内容高度
在安卓自定义渲染器中,通过JavaScript获取网页内容高度,再同步给WebView,同时禁用WebView自身滚动避免冲突:
public class DailyReadingAndroidRenderer : WebViewRenderer { public DailyReadingAndroidRenderer(Context context) : base(context) { } protected override void OnElementChanged(ElementChangedEventArgs<Microsoft.Maui.Controls.WebView> e) { base.OnElementChanged(e); if (Control != null) { // 禁用WebView自身滚动,避免与外层ScrollView冲突 Control.VerticalScrollBarEnabled = false; Control.HorizontalScrollBarEnabled = false; // 基础WebView配置 Control.Settings.DefaultFontSize = 25; Control.Settings.JavaScriptEnabled = true; Control.SetBackgroundColor(Android.Graphics.Color.Transparent); Control.SetLayerType(Android.Views.LayerType.Software, null); Control.Settings.SetSupportZoom(false); // 注入样式+获取内容高度的脚本 string script = @" let style = document.createElement('style'); style.innerHTML = @font-face { font-family: 'CustomFont'; src: url('file:///android_asset/Poppins-Light.ttf'); } body { background-color: transparent !important; color: black !important; font-family: 'CustomFont', sans-serif !important; margin: 0; padding: 0; } h4 { color: #679E18 !important; } ; document.head.appendChild(style); // 将网页高度传递给原生端 window.android.getDocumentHeight(document.body.scrollHeight); "; Control.SetWebViewClient(new CustomWebViewClient(script)); // 添加JS接口接收高度数据 Control.AddJavascriptInterface(new WebViewJsInterface(Element), "android"); } } private class CustomWebViewClient : WebViewClient { private readonly string _script; public CustomWebViewClient(string script) => _script = script; public override void OnPageFinished(Android.Webkit.WebView view, string url) { base.OnPageFinished(view, url); view.EvaluateJavascript(_script, null); } } // JS交互类,用于接收网页高度 private class WebViewJsInterface : Java.Lang.Object { private readonly Microsoft.Maui.Controls.WebView _webView; public WebViewJsInterface(Microsoft.Maui.Controls.WebView webView) => _webView = webView; [Android.Webkit.JavascriptInterface] public void GetDocumentHeight(int height) { // 转换安卓px为MAUI dp单位 float density = Android.App.Application.Context.Resources.DisplayMetrics.Density; int dpHeight = (int)(height / density); // 在UI线程更新WebView高度 Microsoft.Maui.Controls.Device.BeginInvokeOnMainThread(() => { _webView.HeightRequest = dpHeight; }); } } }
方案3:拆分布局避免嵌套(变通方案)
如果布局允许,将WebView与ScrollView拆分到不同的Grid行,只让需要滚动的元素放在ScrollView中:
<Frame Margin="10,0,10,0" x:Name="android_uwp_layout" IsVisible="False" Padding="5" CornerRadius="20" Grid.Row="1"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <!-- WebView和背景图单独占一行,不嵌套ScrollView --> <Grid Grid.Row="0"> <Image Aspect="Fill" HorizontalOptions="FillAndExpand" Source="ic_daily_reading_new_bg_xx.png"/> <local:DailyReadingAndroidWebView x:Name="mywebview" BackgroundColor="Transparent" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"/> </Grid> <!-- 其他需要滚动的元素放在ScrollView中 --> <ScrollView Grid.Row="1" Orientation="Vertical" VerticalOptions="FillAndExpand"> <!-- 其他UI元素 --> </ScrollView> </Grid> </Frame>
注意事项
- 必须禁用WebView自身滚动条,避免与外层ScrollView的滚动逻辑冲突。
- 动态计算高度时要做好单位转换,防止高度显示异常。
- 若WebView内容动态更新,需重新执行高度计算脚本。
内容的提问来源于stack exchange,提问作者Matthew Pans
相关产品推荐
相关产品推荐

