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

Flutter中WebView Bottom Sheet无法滚动问题求助

解决Bottom Sheet中WebView无法滚动的问题

问题描述

已实现WebView在Bottom Sheet中打开的功能,但打开后Sheet无法滚动,相关代码如下:

触发Bottom Sheet的代码

onTap: () {
  showModalBottomSheet(
    context: context,
    isScrollControlled: true,
    enableDrag: true,
    builder: (context) {
      return DraggableScrollableSheet(
        expand: false,
        initialChildSize: 0.9,
        minChildSize: 0.5,
        maxChildSize: 0.9,
        builder: (context, scrollController) {
          return Column(
            children: [
              Container(
                height: 24,
                alignment: Alignment.center,
                child: Container(
                  width: 40,
                  height: 4,
                  decoration: BoxDecoration(
                    color: Colors.grey[300],
                    borderRadius: BorderRadius.circular(2),
                  ),
                ),
              ),
              Expanded(
                child: SimpleWebViewScreen(
                  url: 'https://arleven.com/projects/San%20Andreas%20Cheats/privacy',
                ),
              ),
            ],
          );
        },
      );
    },
  );
},

WebView页面代码

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

class SimpleWebViewScreen extends StatefulWidget {
  final String url;
  const SimpleWebViewScreen({super.key, required this.url});

  @override
  State<SimpleWebViewScreen> createState() => _SimpleWebViewScreenState();
}

class _SimpleWebViewScreenState extends State<SimpleWebViewScreen> {
  late final WebViewController _controller;

  @override
  void initState() {
    super.initState();
    _controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..loadRequest(Uri.parse(widget.url));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("WebView")),
      body: WebViewWidget(controller: _controller),
    );
  }
}

问题原因

  1. 嵌套Scaffold冲突:SimpleWebViewScreen返回的Scaffold会占用Bottom Sheet的全部可用空间,其内部滚动行为与DraggableScrollableSheet的滚动控制器无关联,导致滚动事件无法正常传递。
  2. 未关联滚动控制器:DraggableScrollableSheet生成的scrollController没有传递给WebView所在的可滚动组件,Sheet无法响应滚动操作。

解决方案

步骤1:修改WebView页面组件

去掉嵌套的Scaffold,添加ScrollController参数,用SingleChildScrollView包裹WebView并关联控制器:

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

class SimpleWebViewScreen extends StatefulWidget {
  final String url;
  final ScrollController? scrollController;
  const SimpleWebViewScreen({super.key, required this.url, this.scrollController});

  @override
  State<SimpleWebViewScreen> createState() => _SimpleWebViewScreenState();
}

class _SimpleWebViewScreenState extends State<SimpleWebViewScreen> {
  late final WebViewController _controller;

  @override
  void initState() {
    super.initState();
    _controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..loadRequest(Uri.parse(widget.url));
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      controller: widget.scrollController,
      child: SizedBox(
        height: MediaQuery.of(context).size.height,
        child: WebViewWidget(controller: _controller),
      ),
    );
  }
}

步骤2:传递滚动控制器给WebView

在DraggableScrollableSheet的builder中,将生成的scrollController传递给SimpleWebViewScreen:

onTap: () {
  showModalBottomSheet(
    context: context,
    isScrollControlled: true,
    enableDrag: true,
    builder: (context) {
      return DraggableScrollableSheet(
        expand: false,
        initialChildSize: 0.9,
        minChildSize: 0.5,
        maxChildSize: 0.9,
        builder: (context, scrollController) {
          return Column(
            children: [
              Container(
                height: 24,
                alignment: Alignment.center,
                child: Container(
                  width: 40,
                  height: 4,
                  decoration: BoxDecoration(
                    color: Colors.grey[300],
                    borderRadius: BorderRadius.circular(2),
                  ),
                ),
              ),
              Expanded(
                child: SimpleWebViewScreen(
                  url: 'https://arleven.com/projects/San%20Andreas%20Cheats/privacy',
                  scrollController: scrollController, // 传递滚动控制器
                ),
              ),
            ],
          );
        },
      );
    },
  );
},

说明

  • 移除Scaffold避免布局嵌套冲突,Bottom Sheet本身作为弹窗容器,无需额外嵌套Scaffold。
  • 通过SingleChildScrollView关联DraggableScrollableSheet的滚动控制器,让Sheet的滚动与WebView内容滚动联动。
  • 设置SizedBox高度为屏幕高度,确保WebView内容能完整展示,支持滚动操作。

内容的提问来源于stack exchange,提问作者Tanu Purohit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 14:55:07