You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中SingleChildScrollView内嵌InAppWebView崩溃及滚动交互实现需求

问题根因

Android 系统对 WebView 最大渲染高度存在16384px的硬限制,你当前通过JS获取内容高度动态修改WebView容器高度的方案,在内容过长时就会超出限制触发IllegalStateException异常。

修复方案

1. 替换动态高度为固定视口高度

废弃动态计算WebView高度的逻辑,直接给WebView设置固定高度,推荐取值为屏幕高度的80%~100%,保证渲染高度不会超出系统阈值:

// 提前获取当前屏幕高度
final screenHeight = MediaQuery.of(context).size.height;

// WebView容器配置
SizedBox(
  // 固定高度,可根据业务场景调整比例
  height: screenHeight * 0.9,
  child: InAppWebview(
    // 开启WebView自身滚动能力
    scrollBarEnabled: true,
    // 注册垂直拖拽手势识别,保证WebView优先消费滚动事件
    gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{
      Factory<VerticalDragGestureRecognizer>(() => VerticalDragGestureRecognizer()),
    },
    // 剩余原有配置保留即可
  ),
)

删除原有onLoadStop中修改_webviewHeightSetInOnLoadStop的逻辑。

2. 实现滚动边界事件透传

通过监听WebView滚动位置,在到达上下边界时将滚动事件透传给外层SingleChildScrollView处理:

  • 首先给外层SingleChildScrollView绑定滚动控制器:
final _outerScrollController = ScrollController();

// 外层滚动容器配置
SingleChildScrollView(
  controller: _outerScrollController,
  // 原有配置保留即可
)
  • 然后在InAppWebview的onScrollChanged回调中处理边界逻辑:
onScrollChanged: (controller, x, y) async {
  // 获取WebView内容总高度和可视高度
  final scrollHeight = await controller.evaluateJavascript(
    source: "document.documentElement.scrollHeight;"
  );
  final clientHeight = await controller.evaluateJavascript(
    source: "document.documentElement.clientHeight;"
  );

  // 滚动到顶部,透传向下拖拽事件给外层滚动容器
  if (y <= 0) {
    _outerScrollController.position.jumpTo(_outerScrollController.offset + y);
  }

  // 滚动到底部,透传向上拖拽事件给外层滚动容器
  if (y + clientHeight >= scrollHeight) {
    final overScrollDelta = y + clientHeight - scrollHeight;
    _outerScrollController.position.jumpTo(_outerScrollController.offset + overScrollDelta);
  }
}

3. 可选优化:消除滚动冲突回弹

可以关闭WebView自身的越界回弹效果,避免和外层滚动的回弹产生冲突:

InAppWebView(
  initialOptions: InAppWebViewGroupOptions(
    android: AndroidInAppWebViewOptions(
      overScrollMode: AndroidOverScrollMode.OVER_SCROLL_NEVER,
    ),
    ios: IOSInAppWebViewOptions(
      bounces: false,
    ),
  ),
  // 原有配置保留即可
)

内容的提问来源于stack exchange,提问作者Stoyan Milev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 22:15:03