问题描述
在 Flutter 中,使用 Webview 时,您有时希望在其上方和下方显示内容。
问题-1? Webview 需要约束,否则无法显示:您需要将 Webview 包装在具有固定大小的容器下或在具有可扩展或类似内容的列下。
问题-2?高度可以很容易地获取,但有时 Webview 会加载异步数据,例如嵌入脚本,这会改变页面的样式。在这种情况下,很难知道如何以及何时获取 Webview 高度。
由于这些问题,大多数时候你的 Webview 会显示一个滚动条,当到达 webview 的底部时,用户将无法滚动你的 Flutter 页面。滚动将与 Webview 冲突。
解决方法
您需要在 html 周围添加额外的内容并使用 javascript 事件处理程序。
我们将稍微自定义一下,而不是将原始 html 传递给 webview。
final htmlFromApi = await getContent();
final html = Uri.dataFromString('''
<html lang="fr">
<meta name="viewport" content="width=device-width user-scalable=no zoom=1.1">
<style>img {max-width: 100%; height: auto}</style>
<body>
<div class="container" id="_flutter_target_do_not_delete">$htmlFromApi</div>
<script>
function outputsize() {
window.flutter_inappwebview.callHandler('newHeight');
}
new ResizeObserver(outputsize).observe(_flutter_target_do_not_delete)
</script>
</body>
</html>
''',mimeType: "text/html",encoding: Encoding.getByName("utf-8")).toString();
如何使用 Webview :
/// Define it to 1 else the Webview widget will not start loading.
double height = 1;
///some widgets
Container(
height: height,child: InAppWebView(
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
supportZoom: false,javaScriptEnabled: true,disableHorizontalScroll: true,disableVerticalScroll: true,),onWebViewCreated: (InAppWebViewController controller) {
controller.addJavaScriptHandler(
handlerName: "newHeight",callback: (List<dynamic> arguments) async {
final int height = await controller.getContentHeight();
setState(() => this.height = height.toDouble());
});
},initialUrl: html,///some widgets
说明:
当 div 内容发生变化时,将发送一个事件。 Flutter InAppWebView 会监听它并调用回调。我们只需使用当前视图高度更新 WebView 的父容器即可。 就是这样,webview 就像一个小部件一样在颤振中显示,没有任何大小问题。