在 SingleChildScrollView 内颤动 InAppWebView

Posted

技术标签:

【中文标题】在 SingleChildScrollView 内颤动 InAppWebView【英文标题】:Flutter InAppWebView inside SingleChildScrollView 【发布时间】:2021-12-18 12:24:02 【问题描述】:

我有一个请求,要制作一张卡片,其中包含一个网页视图和更多小部件。视图应该类似于this。

我做了这样的实现:

SingleChildScrollView(
  ...
  child: Column(
    children: [
      Container(
        ...
        child: Column(
          children: [
            SizedBox(
              height: _webviewHeightSetInOnLoadStop
              child: InAppWebview(
                ...
              )
            ),
            ...
          )
      ),
      Widget1(),
      Widget2(),
      Widget3(),
    ]

_webviewHeightSetInOnLoadStop 设置如下:

  onLoadStop: (controller, url) async 
    final height = await controller.evaluatejavascript(
      source: "document.documentElement.scrollHeight;",
    );
    ...
    setState(() 
      _webviewHeightSetInOnLoadStop = height;
      ...
    );
  

这个实现的问题是,当 webview 太大时,android 会崩溃:

IllegalStateException: Unable to create a layer for InAppWebView, size 960x39192 exceeds max size 16384

据我了解,这是由于 webview 的高度而引发的,这是系统限制的。

所以我想要一种 webview 可滚动的行为,它的容器有一个比屏幕大一点的固定高度(需要时),并且当在任一方向上到达 webview 的滚动结束时,拖动事件被传递给SingleChildScrollView

【问题讨论】:

可以添加_webviewHeightSetInOnLoadStop值吗 @SalihCan 添加了设置_webviewHeightSetInOnLoadStop的onLoadStop方法。 是_webviewHeightSetInOnLoadStop给你39192吗? 【参考方案1】:

我认为您应该实现自定义大小,或者仅针对 webview 容器的预期行为对其进行限制,并使其具有响应性,这样屏幕就不会在旧设备中出现任何崩溃或类似情况。

【讨论】:

【参考方案2】:

还有另一个插件可以完全满足您的需求

webview_flutter_plus: ^0.2.3

试试这个代码

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

import 'package:webview_flutter_plus/webview_flutter_plus.dart';

class ImageEditor extends StatefulWidget 
  const ImageEditor(Key? key) : super(key: key);

  @override
  _ImageEditorState createState() => _ImageEditorState();


class _ImageEditorState extends State<ImageEditor> 
  WebViewPlusController? _controller;
  double _height = 1;

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Container(
        height:MediaQuery.of(context).size.height,
        width: MediaQuery.of(context).size.width,
        child: SingleChildScrollView(
          child: Column(
            children: [
              SizedBox(
                height: _height,
                child: WebViewPlus(
                  onWebViewCreated: (controller) 
                    this._controller = controller;      controller.loadUrl('https://pub.dev/packages/webview_flutter_plus');
              ,
              onPageFinished: (url) 

                _controller!.getHeight().then((double height) 
                  print("Height:  " + height.toString());
                  setState(() 
                    _height = height;
                  );
                );
              ,
              javascriptMode: JavascriptMode.unrestricted,
            ),
          ),
          Container(
            height:200,
            width: MediaQuery.of(context).size.width,
            color: Colors.red,
          ),
          Container(
            height:200,
            width: MediaQuery.of(context).size.width,
            color: Colors.black,
          ),
          Container(
            height:200,
            width: MediaQuery.of(context).size.width,
            color: Colors.green,
            ),
           ],
          ),
        ),
      ),
    );
  

【讨论】:

这并不能解决旧 Android 设备(例如 Android 8)上 Webview 崩溃的问题。当到达 Webview 的滚动结束时,我可能需要一个解决方案来处理来自 SingleChildScrollView 的触摸事件。 编辑了我的答案。请检查 我试过了,Webview 仍然崩溃。在该示例中,开发人员正在做完全相同的事情 - 使用 javascript 获取 Web 视图高度并将其设置为大小盒高度。崩溃是由 Webview 的内容高度过大引起的。这就是为什么我需要一个解决方案,在需要时由 SingleChildScrollView 和 Webview 处理手势。 如果你不介意可以发post网页的url 可以是任何内容足够长的网页。

以上是关于在 SingleChildScrollView 内颤动 InAppWebView的主要内容,如果未能解决你的问题,请参考以下文章

键盘溢出 * 像素。无法使用 SingleChildScrollView 或 ListView

如何在TabBarView中实现SingleChildScrollView(带有水平列表视图和垂直gridview)

如何使 SingleChildScrollView 中的 Wrap 小部件子级在 Flutter 中扩展到全高?

Flutter:SingleChildScrollView 内的 TabBarView

SingleChildScrollView ,子列上的空格问题

Flutter ListView scrollPhysics 在 SingleChildScrollView 中不起作用