Flutter实现后台/非活跃时用启动页隐藏应用内容(替代FLAG_SECURE黑屏)
Flutter后台显示启动页替代FLAG_SECURE黑屏的实现方案
需求说明
开发Flutter应用时,需在应用进入后台时显示启动页,替代FLAG_SECURE(Android)或模糊效果(iOS)导致的黑屏,提升用户体验。
实现方案:基于Method Channel自定义实现
Android平台修改
1. 创建启动页布局
在res/layout/下新建splash_screen.xml,添加启动页UI(示例为居中logo):
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white" android:gravity="center"> <ImageView android:layout_width="200dp" android:layout_height="200dp" android:src="@drawable/app_logo" /> </LinearLayout>
2. 修改MainActivity代码
替换原有的FLAG_SECURE逻辑,改为添加/移除启动页覆盖层:
class MainActivity: FlutterFragmentActivity() { private val CHANNEL = "security" private var splashOverlay: View? = null override fun onCreate(savedInstanceState: Bundle?) { if (intent.getIntExtra("org.chromium.chrome.extra.TASK_ID", -1) == this.taskId) { this.finish() intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } super.onCreate(savedInstanceState) } override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) setupMethodChannel(flutterEngine) } private fun setupMethodChannel(flutterEngine: FlutterEngine) { MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> when (call.method) { "enableAppSecurity" -> { enableAppSecurity() result.success(null) } "disableAppSecurity" -> { disableAppSecurity() result.success(null) } else -> result.notImplemented() } } } override fun onWindowFocusChanged(hasFocus: Boolean) { super.onWindowFocusChanged(hasFocus) toggleAppSecurity(hasFocus) } override fun onPause() { super.onPause() enableAppSecurity() } override fun onResume() { super.onResume() disableAppSecurity() } private fun toggleAppSecurity(hasFocus: Boolean) { if (hasFocus) { disableAppSecurity() } else { enableAppSecurity() } } private fun enableAppSecurity() { if (splashOverlay == null) { splashOverlay = layoutInflater.inflate(R.layout.splash_screen, null) val params = WindowManager.LayoutParams( WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_APPLICATION, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT ) window.addContentView(splashOverlay, params) } } private fun disableAppSecurity() { splashOverlay?.let { (it.parent as ViewGroup).removeView(it) splashOverlay = null } } }
iOS平台修改
1. 准备启动页资源
确保项目中已存在启动图资源(LaunchImage或LaunchScreen.storyboard)。
2. 修改AppDelegate代码
替换原模糊效果逻辑,改为显示启动页:
@UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { private var flutterViewController: FlutterViewController! private var securityChannel: FlutterMethodChannel! private var splashView: UIView? private var isInBackground: Bool = false override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) setupFlutterCommunication() return super.application(application, didFinishLaunchingWithOptions: launchOptions) } private func setupFlutterCommunication() { flutterViewController = window?.rootViewController as? FlutterViewController securityChannel = FlutterMethodChannel( name: "security", binaryMessenger: flutterViewController.binaryMessenger ) securityChannel.setMethodCallHandler(handle) } override func applicationDidEnterBackground(_ application: UIApplication) { isInBackground = true enableAppSecurity() } override func applicationDidBecomeActive(_ application: UIApplication) { if isInBackground { disableAppSecurity() isInBackground = false } } private func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { switch call.method { case "enableAppSecurity": enableAppSecurity() result(nil) case "disableAppSecurity": disableAppSecurity() result(nil) default: result(FlutterMethodNotImplemented) } } private func enableAppSecurity() { // 方式1:使用LaunchScreen.storyboard let splashViewController = UIStoryboard(name: "LaunchScreen", bundle: nil).instantiateInitialViewController() splashView = splashViewController?.view splashView?.frame = window!.frame window?.addSubview(splashView!) // 方式2:直接使用启动图(二选一) // let launchImage = UIImage(named: "LaunchImage") // splashView = UIImageView(image: launchImage) // splashView?.frame = window!.frame // (splashView as? UIImageView)?.contentMode = .scaleAspectFill // window?.addSubview(splashView!) } private func disableAppSecurity() { splashView?.removeFromSuperview() splashView = nil } }
第三方包推荐
目前没有专门针对“后台显示启动页”的Flutter第三方包,自定义Method Channel实现更灵活可控,可根据应用启动页的设计自由调整UI。
内容的提问来源于stack exchange,提问作者Muhammad Arsalan
相关产品推荐
相关产品推荐

