在Xamarin.Forms中,WebView如果嵌套在StackLayout和RelativeLayout中必须要设置HeightRequest和WidthRequest属性才会进行渲染。可是在实际项目中往往WebView内容是不固定的,就造成了设置了HeightRequest和WidthRequest后显示效果不理想,不是高了就是短了,很影响用户体验,那么就必须要自适应网页的高度才行。
首先在共享库中的添加XamWebView类:
public class XamWebView: WebView {}
然后使用它:
var webview= new XamWebView();
webview.HorizontalOptions = LayoutOptions.Fill;
webview.VerticalOptions = LayoutOptions.StartAndExpand; //给个默认的高度和宽度 webview.WidthRequest = 300;
webview.HeightRequest = 300;
webview.Source = "https://www.cnblogs.com/";
然后在IOS中,你需要使用自定义的委托:
[assembly: ExportRenderer (typeof(XamWebView), typeof(XamWebViewRenderer))] namespace Core.iOS { public class XamWebViewRenderer : WebViewRenderer { protected override void OnElementChanged (VisualElementChangedEventArgs e) { base.OnElementChanged (e);
Delegate = new XamUIWebViewDelegate (this);
}
}
}
然后用异步和小延迟重写LoadFinished以获取整个ContentSize.Height(如果内容较大,即使加载完成后也需要一些时间才能呈现)
public class XamUIWebViewDelegate : UIWebViewDelegate {
XamWebViewRenderer webViewRenderer; public XamUIWebViewDelegate (XamWebViewRenderer _webViewRenderer = null) {
webViewRenderer = _webViewRenderer ?? new XamWebViewRenderer ();
} public override async void LoadingFinished (UIWebView webView) { var wv = webViewRenderer.Element as XamWebView; if (wv != null) { await System.Threading.Tasks.Task.Delay (100); // 这里的时间可以调整 wv.HeightRequest = (double)webView.ScrollView.ContentSize.Height;
}
}
}
在Android中,您需要使用自定义的Android.Webkit.WebViewClient:
using WebView = Android.Webkit.WebView;
[assembly: ExportRenderer (typeof(XamWebView), typeof(XamWebViewRenderer))] namespace Core.Droid { public class XamWebViewRenderer : WebViewRenderer { static XamWebView _xwebView = null;
WebView _webView; public XamWebViewRenderer(Context context) : base(context) {
} class XamWebViewClient : Android.Webkit.WebViewClient { public override async void OnPageFinished(WebView view, string url) { if (_xwebView != null)
{ int i = 10; while (view.ContentHeight == 0 && i-- > 0) await System.Threading.Tasks.Task.Delay(100);// 这里的时间可以调整 _xwebView.HeightRequest = view.ContentHeight;
}
}
} protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e) { base.OnElementChanged(e);
_xwebView = e.NewElement as XamWebView;
_webView = Control; if (e.OldElement == null)
{
_webView.SetWebViewClient(new XamWebViewClient());
}
}
}
}
放一张Android截图: