Flutter开发APK时状态栏重叠遮挡WebView屏幕如何解决?
Flutter WebView顶部被状态栏遮挡适配方案
问题表现
打包APK运行后,WebView组件顶部内容被系统状态栏覆盖,需要在保留状态栏正常显示的前提下,让WebView不与状态栏重叠,自动占满状态栏以外的所有屏幕可用空间。
问题效果截图
当前出问题的代码如下:
import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; void main() { runApp(const myapp()); } // ignore: camel_case_types class myapp extends StatelessWidget { const myapp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: "Sample App", theme: ThemeData( primarySwatch: Colors.red, ), home: const Scaffold( appBar: null, body: WebView( initialUrl: 'https://primexop.com/motap/appw1/index.php?app_v=1.001010&ow_id=101', javascriptMode: JavascriptMode.unrestricted, )), ); } }
问题原因
Scaffold在不设置AppBar的情况下,默认不会自动给body区域添加状态栏高度的顶部内边距,body内容会直接从屏幕最顶部开始布局,自然就会压到状态栏下方出现遮挡。
解决方法
方法一:SafeArea包裹(零额外配置,优先使用)
直接给WebView外层套一层SafeArea,组件会自动识别设备的系统安全区域(状态栏、底部导航条、刘海屏挖孔区域等),自动添加对应边距,保证内容不会被系统UI遮挡。
修改后的Scaffold代码:
home: const Scaffold( appBar: null, body: SafeArea( child: WebView( initialUrl: 'https://primexop.com/motap/appw1/index.php?app_v=1.001010&ow_id=101', javascriptMode: JavascriptMode.unrestricted, ), ), ),
如果只需要适配顶部状态栏,不需要给底部、左右侧边加安全区限制,可以给SafeArea传对应参数控制:
SafeArea( top: true, // 开启顶部状态栏适配 bottom: false, // 关闭底部安全区适配 left: false, right: false, child: const WebView(/* WebView配置保持不变 */) )
方法二:手动获取状态栏高度加边距(适合需要自定义状态栏样式的场景)
如果需要自定义状态栏颜色、状态栏图标明暗度,可以用这个方案,灵活度更高。
- 先导入服务包,在runApp前初始化系统UI配置,避免状态栏被隐藏:
import 'package:flutter/services.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); // 配置状态栏样式,不会隐藏状态栏 SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( statusBarColor: Colors.transparent, // 状态栏背景透明 statusBarIconBrightness: Brightness.dark, // 状态栏图标为深色,浅色背景用这个配置 statusBarBrightness: Brightness.light, )); runApp(const myapp()); }
- 通过MediaQuery获取当前设备的状态栏高度,手动给WebView加顶部内边距:
home: Scaffold( appBar: null, body: Builder( builder: (context) { final double topPadding = MediaQuery.of(context).padding.top; return Padding( padding: EdgeInsets.only(top: topPadding), child: const WebView( initialUrl: 'https://primexop.com/motap/appw1/index.php?app_v=1.001010&ow_id=101', javascriptMode: JavascriptMode.unrestricted, ), ); }, ), ),
避坑提示
- 不要随意调用
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive)/SystemUiMode.edgeToEdge这类全屏配置,这类配置会让应用内容铺满整个屏幕(包括状态栏区域),必然会出现内容遮挡问题。 - 如果使用的是4.0及以上版本的webview_flutter,WebView需要配合WebViewController初始化,但安全区适配的逻辑完全不受影响,套在组件最外层即可。
内容的提问来源于stack exchange,提问作者Adarsh Hatkar
相关产品推荐
相关产品推荐

