【问题标题】:WebView without height inside Scroll not working滚动内没有高度的WebView不起作用
【发布时间】:2019-11-04 13:23:35
【问题描述】:

在 Flutter 上...我尝试在所有支持滚动的可用容器中添加 Webview,但它在 Android 上不起作用。

ListView(
          shrinkWrap: true,
          children: <Widget>[
            Text("hiiiiiiiiiiiii "),
            Text("hiiiiiiiiiiiii "),
            Text("hiiiiiiiiiiiii "),
           Expanded(
                child: WebView(
                    key: Key("webview1"),
                    debuggingEnabled:  true,
                    javascriptMode: JavascriptMode.unrestricted,
                    initialUrl: "https://flutter.dev/")),
            Text("hiiiiiiiiiiiii "),
            Text("hiiiiiiiiiiiii "),
            Text("hiiiiiiiiiiiii "),
          ],
)

【问题讨论】:

  • 查看这里:medium.com/flutter/…
  • 我检查了这篇文章,但它对我不起作用。似乎在 Scroll 容器上添加 Webview 是 Fl​​utter 最薄弱的地方之一
  • 你能分享一些可编译的代码来检查吗?
  • 我在描述中添加了 ListView 代码

标签: flutter webview


【解决方案1】:

如果您想将可滚动的 WebView 放在其他小部件之间,并且 WebView 将是可滚动的,而其他小部件则不是,那么只需像这样更改您的 ListView 为 Column:

Column(
  children: <Widget>[
    Text("hiiiiiiiiiiiii "),
    Text("hiiiiiiiiiiiii "),
    Container(
      height: 300,
      child: WebView(
          key: Key("webview1"),
          debuggingEnabled: true,
          javascriptMode: JavascriptMode.unrestricted,
          initialUrl: "https://flutter.dev/")
    ),
    Text("hiiiiiiiiiiiii "),
    Text("hiiiiiiiiiiiii "),
)

但是,如果您想在 WebView 上添加一些可滚动的小部件,请尝试 CustomScrollViewSliverList

你能说出你想要做出的确切逻辑吗?

补充:

如果你想在里面有可滚动区域和一些WebView,你必须知道WebView的高度:

ListView(
  physics: ClampingScrollPhysics(),
  children: <Widget>[
    Text("hiiiiiiiiiiiii "),
    Text("hiiiiiiiiiiiii "),
    ConstrainedBox(
      constraints: BoxConstraints(maxHeight: 10000),
        child: WebView(
          gestureRecognizers: Set()
            ..add(
              Factory<VerticalDragGestureRecognizer>(
                  () => VerticalDragGestureRecognizer(),
              ), // or null
            ),
            key: Key("webview1"),
            debuggingEnabled: true,
            javascriptMode: JavascriptMode.unrestricted,
            initialUrl: "https://flutter.dev/")),
    Text("hiiiiiiiiiiiii "),
    Text("hiiiiiiiiiiiii "),
  ],
);

你可以动态获得的 WebView 的高度,灵感就在这里: https://gist.github.com/PonnamKarthik/877a90917a576ecff613d5169680d02c

【讨论】:

  • 我想制作一个完整的可滚动小部件,其中包含 WebView(具有动态高度,内部没有滚动)和它上面和下面的其他容器。都应该在父 Widget 内滚动。
  • WebView 小部件就像一个带有滚动条的浏览器,您可以禁用滚动,我的意思是内部滚动,但是您必须知道该小部件的确切高度,否则它不会工作。
  • 我如何知道 Webview 的高度包含 iframe、画廊和视频。在 Native Android App 上,我可以将 webview 放在 nestedscrollview 中,而无需为 webview 添加高度,并且效果很好。我知道 Flutter 上的 Webview 是基于 Native Webview 的,所以为什么滚动功能不能像原生一样工作
  • 我根据您的需要更改了我的解决方案。在这个例子中你可以得到的 WebView 的高度:gist.github.com/PonnamKarthik/877a90917a576ecff613d5169680d02c
  • 好的,我会检查你的解决方案并反馈给你
【解决方案2】:

感谢 dubace 提供的解决方案 gist.github.com/PonnamKarthik/877a90917a576ecff613d5169680d02c

问题解决了,现在我们可以在父可滚动容器中添加 Webview。

导入 'dart:convert';

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Code Sample',
      builder: (BuildContext context, Widget navigator) {
        return MyStatelessWidget();
      },
    );
  }
}

class MyStatelessWidget extends StatefulWidget {
  MyStatelessWidget({Key key}) : super(key: key);

  @override
  _MyStatelessWidgetState createState() => _MyStatelessWidgetState();
}

class _MyStatelessWidgetState extends State<MyStatelessWidget> {
  List<WebViewController> _listController = List();

  List<double> _heights =
      List<double>.generate(htmlStrings.length, (int index) => 20.0);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        shrinkWrap: true,
        itemCount: htmlStrings.length,
        itemBuilder: (context, index) {
          return Container(
            height: _heights[index] ?? 100.0,
            child: WebView(
              initialUrl:
                  'data:text/html;base64,${base64Encode(const Utf8Encoder().convert(htmlStrings[index]))}',
              onPageFinished: (some) async {
                double height = double.parse(await _listController[index]
                    .evaluateJavascript(
                        "document.documentElement.scrollHeight;"));
                setState(() {
                  _heights[index] = height;
                });
              },
              javascriptMode: JavascriptMode.unrestricted,
              onWebViewCreated: (controller) async {
                _listController.add(controller);
              },
            ),
          );
        },
      ),
    );
  }
}

final List<String> htmlStrings = [
  '''<p>Table shows some compounds and the name of their manufacturing process</p>
<table style="border-collapse: collapse; width: 100%; height: 85px;" border="1">
<tbody>
<tr style="height: 17px;">
<td style="width: 50%; text-align: center; height: 17px;">Compounds/Elements</td>
<td style="width: 50%; text-align: center; height: 17px;">Manufacture process</td>
</tr>
<tr style="height: 17px;">
<td style="width: 50%; height: 17px;">Nitric acid</td>
<td style="width: 50%; height: 17px;">Ostwald's process</td>
</tr>
<tr style="height: 17px;">
<td style="width: 50%; height: 17px;">Ammonia</td>
<td style="width: 50%; height: 17px;">Haber's process</td>
</tr>
<tr style="height: 17px;">
<td style="width: 50%; height: 17px;">Sulphuric acid</td>
<td style="width: 50%; height: 17px;">Contact process</td>
</tr>
<tr style="height: 17px;">
<td style="width: 50%; height: 17px;">Sodium</td>
<td style="width: 50%; height: 17px;">Down's process</td>
</tr>
</tbody>
</table>''',
  '''<p>\(L=[M{L }^{2 }{T }^{-2 }{A }^{-2 }]\)</p>
<p>\(C=[{M }^{-1 }{L }^{-2 }{T }^{4 }{A }^{2 }]\)</p>
<p>\(R=[M{L }^{2 }{T }^{-3 }{A }^{-2 }]\)</p>
<p>\(\therefore \frac {R}{L}=\frac{[M{L }^{2 }{T }^{-2 }{A }^{-2 }]}{[M{L }^{2 }{T }^{-3 }{A }^{-2 }]}=[T]\)</p>''',
  '''<p>Displacement(s)\(=\left(13.8\pm0.2\right)m\)</p>
<p>Time(t)\(=\left(4.0\pm0.3\right)s\)</p>
<p>Velocity(v)\(=\frac{13.8}{4.0}=3.45m{s}^{-1}\)</p>
<p>\(\frac{\delta v}{v}=\pm\left(\frac{\delta s}{s}+\frac{\delta t}{t}\right)=\pm\left(\frac{0.2}{13.8}+\frac{0.3}{4.0}\right)=\pm0.0895\)</p>
<p>\(\delta v =\pm0.0895*3.45=\pm0.3\)(rounding off to one place of decimal)</p>
<p>\(v=\left(3.45\pm0.3\right)m{s}^{-1}\)</p>''',
  '''<p>The only real numbers satisfying \(x^2=4\) are 2 and -2. But none of them satisfy the final condition, \(x+2=3\). So, there is no real number such that these conditions are met. Hence this is null set.</p>
<p>Note that, for \(x\) to be a memner of \(\{x:p(x),q(x)\}\),&nbsp;<em><strong>both</strong></em> \(p(x)\) and \(q(x)\) should be true.</p>''',
];

【讨论】:

    【解决方案3】:

    制作一个完全可滚动的 Widget,包含 WebView(具有动态高度)和它上面和下面的其他容器。都应该在父 Widget 内滚动

    确保正确安装了flutter package:webview_flutter: ^1.0.5

    1.创建Futurefxn

                   `String hight;
                    double webHight =400; //default some value
               Future funcThatMakesAsyncCall() async{
                      var result =
                     await controller.evaluateJavascript('document.body.scrollHeight'); 
        //here we call javascript for get browser data
                        setState(() {
                                    hight = result;
                                     },
                                    );
                                                  }
    

    `

    2.我们使用SingleChildScrollView 滚动方向:Axis.vertical,

    3.内部使用Column

    4.最后我们使用Conatiner

    Container 中,我们使用WebView

    这里Container代码

                   `Container(
                    height: webHight+20,
                    child: WebView(
                    initialUrl: widget.url,
                    onPageFinished: (webhight)async{
                       await funcThatMakesAsyncCall();
                       setState((){
                          webHight= double.parse(hight);                          
                       });                        
                      },
                      javascriptMode: JavascriptMode.unrestricted,
                      onWebViewCreated: (WebViewController webViewController) {
                      
                      controller = webViewController;
    
                      },
                    ),
                  ),`
    

    【讨论】:

      【解决方案4】:

      一开始我也遇到了同样的问题。您可以指定通过哪些手势 使用 gestureRecognizers 参数转到 webView 小部件。下面的代码有助于捕获垂直滚动事件。

             WebView(
             initialUrl: someUrl,
             gestureRecognizers: Set()
              ..add(Factory<VerticalDragGestureRecognizer>(
               () => VerticalDragGestureRecognizer())),
             )
      

      我发现这篇文章对 webview 也很有用 The Power of WebViews in Flutter

      【讨论】:

        猜你喜欢
        • 2018-01-23
        • 2014-09-16
        • 2014-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多