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), ); } }
问题原因
- 嵌套Scaffold冲突:
SimpleWebViewScreen返回的Scaffold会占用Bottom Sheet的全部可用空间,其内部滚动行为与DraggableScrollableSheet的滚动控制器无关联,导致滚动事件无法正常传递。 - 未关联滚动控制器:
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
相关产品推荐
相关产品推荐

