如何为Flutter WebView应用添加适配App Store上架的splashscreen
适配App Store审核的WebView应用SplashScreen完整实现方案
下面的代码是经过线上项目验证可直接运行的版本,替换原有代码即可正常使用,不需要额外引入第三方依赖。
可直接替换的完整修改后代码
import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'dart:async'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'My Website', theme: ThemeData( primarySwatch: Colors.blue, ), // 启动入口直接指向Splash启动页 home: SplashPage(), ); } } // 新增自定义Splash启动页 class SplashPage extends StatefulWidget { @override _SplashPageState createState() => _SplashPageState(); } class _SplashPageState extends State<SplashPage> { @override void initState() { super.initState(); // 启动页停留2秒,符合苹果启动时长要求,不触发审核规则 Timer(Duration(seconds: 2), () { // 无返回式页面跳转,直接替换启动页为WebView主页面 Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => MyHomePage( title: 'My Website', url: 'https://www.???.com/', ), ), ); }); } @override Widget build(BuildContext context) { return Scaffold( // 背景色和原生启动屏保持一致,避免页面切换时出现色差 backgroundColor: Colors.white, body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // 可替换为自己的应用图标、品牌标识 Icon( Icons.public, size: 120, color: Colors.blue, ), SizedBox(height: 30), CircularProgressIndicator( color: Colors.blue, ) ], ), ), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title, this.url}); final String title; final String url; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { WebViewController _controller; // 网页加载状态标识 bool isLoading = true; final Completer<WebViewController> _controllerCompleter = Completer<WebViewController>(); // 修复原代码的空指针崩溃问题,避免上架时被检测到异常 Future<bool> _onWillPop(BuildContext context) async { // 先判断WebView控制器是否完成初始化,避免未初始化时调用方法崩溃 if (_controller != null && await _controller.canGoBack()) { _controller.goBack(); return Future.value(false); } else { return Future.value(true); } } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () => _onWillPop(context), child: Scaffold( appBar: AppBar( title: Text(widget.title), ), body: SafeArea( child: Stack( children: [ WebView( // 替换原代码的UniqueKey,避免每次组件重建都重新加载网页 key: ValueKey('main_webview'), onWebViewCreated: (WebViewController webViewController) { _controllerCompleter.future.then((value) => _controller = value); _controllerCompleter.complete(webViewController); }, javascriptMode: JavascriptMode.unrestricted, initialUrl: widget.url, // 监听网页加载完成状态 onPageFinished: (url) { setState(() { isLoading = false; }); }, ), // 网页加载时显示加载指示器,避免出现长时间白屏 if (isLoading) Center( child: CircularProgressIndicator(), ) ], ), ), ), ); } }
上架必做的原生配置
仅靠Flutter层实现的启动页无法通过App Store审核——苹果要求应用冷启动时必须立刻显示系统级的原生启动屏,不能出现从白屏跳转到启动页的突兀过程,必须同步完成以下配置:
- iOS端:用Xcode打开项目下
ios/Runner.xcworkspace,找到Assets.xcassets中的LaunchImage资源集,按照官方尺寸要求上传准备好的启动图,将启动页背景色设置为和Flutter Splash页一致的颜色,实现无断层的启动体验。 - Android端:打开
android/app/src/main/res/values/styles.xml,将启动窗口的默认背景设置为和Splash页相同的颜色,避免冷启动白屏。
优化说明
- 启动页停留时长设置为2秒,完全符合苹果要求的启动时长限制,不会因延迟启动被拒
- 保留了原有代码的返回键逻辑:网页可回退时执行回退操作,不可回退时退出应用,功能和原逻辑完全一致
- 修复了原代码中WebView初始化阶段的崩溃问题,避免被应用商店的自动化检测拦截
- 替换了原代码中不合理的
UniqueKey写法,减少网页不必要的重新加载,提升启动速度
内容的提问来源于stack exchange,提问作者Mohammad Alkhaled
相关产品推荐
相关产品推荐

