【问题标题】:Flutter and InAppWebView How to get height?Flutter 和 InAppWebView 如何获取高度?
【发布时间】:2021-06-03 05:29:24
【问题描述】:

在flutter中,在使用Webview的时候,有时想要在其上方和下方显示内容。

问题 - 1 ? Webview 需要约束,否则无法显示:您需要将 Webview 包装在具有固定大小的容器下或具有可扩展或类似内容的列下。

问题 - 2?高度可以很容易地获取,但有时 Webview 会加载异步数据,例如嵌入脚本,这会改变页面的样式。在这种情况下,很难知道如何以及何时获取 Webview 高度。

由于这些问题,大多数时候您的 Webview 会显示一个滚动条,当到达 webview 的底部时,用户将无法滚动您的颤动页面。滚动会与 Webview 冲突。

解决这个问题的最佳方法是什么?

【问题讨论】:

    标签: flutter flutter-inappwebview


    【解决方案1】:

    您需要在 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() {
                                    if (typeof window.flutter_inappwebview !== "undefined" && typeof window.flutter_inappwebview.callHandler !== "undefined")
                                       window.flutter_inappwebview.callHandler('newHeight', document.getElementById("_flutter_target_do_not_delete").offsetHeight);
                                    }
                                  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 {
              int? height = arguments.isNotEmpty ? arguments[0] : await controller.getContentHeight();
              if (mounted) setState(() => this.height = height!.toDouble());
            });
        },
        initialUrl: html,
      ),
    ),
    ///some widgets
    

    解释:

    当 div 内容发生变化时,将发送一个具有新大小的事件。 Flutter InAppWebView 会监听它并调用回调。我们只需要用当前视图高度更新 WebView 的父容器。 就是这样,webview 像一个小部件一样显示在颤动中,没有任何大小问题。

    【讨论】:

    • 后期编辑,我使用了参数中的额外尺寸。
    【解决方案2】:
          int? contentHeight = await _controller?.getContentHeight();
                double? zoomScale = await _controller?.getZoomScale();
                double htmlHeight = contentHeight!.toDouble() * zoomScale!;
                double htmlHeightFixed =
                    double.parse(htmlHeight.toStringAsFixed(2));
                if (htmlHeightFixed == 0.0) {
                  return;
                }
                setState(() {
                  _htmlHeight = htmlHeightFixed + 0.1;
                });
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 2018-10-09
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 2018-08-22
    • 1970-01-01
    • 2019-12-26
    • 2011-07-12
    • 2014-05-01
    相关资源
    最近更新 更多