如何检测Flutter框架中Native Dialog是否已打开?
检测Flutter中Native Dialog的打开状态
Flutter框架本身没有提供直接检测Native Dialog是否打开的API,但可以通过**平台通道(MethodChannel)**结合原生代码实现状态同步,以此区分Native Dialog触发的inactive状态和其他场景。
实现思路
在原生层(Android/iOS)监听Native Dialog的显示与隐藏事件,通过MethodChannel将状态同步到Flutter侧,Flutter维护一个全局状态变量,后续即可在App生命周期回调中判断当前是否是Native Dialog导致的状态变化。
Android端实现
1. 配置MethodChannel与状态管理
在MainActivity中创建MethodChannel,维护Native Dialog的显示状态,并提供状态查询方法:
class MainActivity : FlutterActivity() { private lateinit var channel: MethodChannel private var isNativeDialogShowing = false override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "native_dialog_channel") channel.setMethodCallHandler { call, result -> when (call.method) { "isNativeDialogShowing" -> result.success(isNativeDialogShowing) else -> result.notImplemented() } } } // Dialog显示时调用,同步状态到Flutter fun onNativeDialogShow() { isNativeDialogShowing = true channel.invokeMethod("onNativeDialogStateChanged", true) } // Dialog关闭时调用,同步状态到Flutter fun onNativeDialogDismiss() { isNativeDialogShowing = false channel.invokeMethod("onNativeDialogStateChanged", false) } }
2. 在Native Dialog调用处同步状态
显示AlertDialog时,调用状态同步方法:
AlertDialog.Builder(this) .setTitle("提示") .setMessage("这是Native Dialog") .setPositiveButton("确定") { dialog, _ -> dialog.dismiss() (this as MainActivity).onNativeDialogDismiss() } .show().also { (this as MainActivity).onNativeDialogShow() }
iOS端实现
1. 配置MethodChannel与状态管理
在AppDelegate中创建MethodChannel并维护状态:
import UIKit import Flutter @UIApplicationMain class AppDelegate: FlutterAppDelegate { private var channel: FlutterMethodChannel! private var isNativeDialogShowing = false override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let controller = window?.rootViewController as! FlutterViewController channel = FlutterMethodChannel(name: "native_dialog_channel", binaryMessenger: controller.binaryMessenger) channel.setMethodCallHandler { [weak self] call, result in guard let self = self else { return } switch call.method { case "isNativeDialogShowing": result.success(self.isNativeDialogShowing) default: result.notImplemented() } } GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } // 同步Dialog显示状态到Flutter func onNativeDialogShow() { isNativeDialogShowing = true channel.invokeMethod("onNativeDialogStateChanged", arguments: true) } // 同步Dialog关闭状态到Flutter func onNativeDialogDismiss() { isNativeDialogShowing = false channel.invokeMethod("onNativeDialogStateChanged", arguments: false) } }
2. 在Native Dialog调用处同步状态
显示UIAlertController时调用状态同步方法:
let alert = UIAlertController(title: "提示", message: "这是Native Dialog", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default) { _ in (UIApplication.shared.delegate as! AppDelegate).onNativeDialogDismiss() }) present(alert, animated: true) { (UIApplication.shared.delegate as! AppDelegate).onNativeDialogShow() }
Flutter端实现
1. 状态管理类
创建单例类维护Native Dialog状态,接收原生层的状态通知:
import 'package:flutter/services.dart'; class NativeDialogMonitor { static final NativeDialogMonitor _instance = NativeDialogMonitor._internal(); factory NativeDialogMonitor() => _instance; NativeDialogMonitor._internal() { _channel.setMethodCallHandler(_handleMethodCall); } final MethodChannel _channel = const MethodChannel('native_dialog_channel'); bool _isNativeDialogShowing = false; /// 获取当前Native Dialog是否显示 bool get isNativeDialogShowing => _isNativeDialogShowing; Future<void> _handleMethodCall(MethodCall call) async { switch (call.method) { case 'onNativeDialogStateChanged': _isNativeDialogShowing = call.arguments as bool; break; default: throw MissingPluginException(); } } /// 主动查询Native Dialog状态 Future<bool> checkNativeDialogState() async { return await _channel.invokeMethod('isNativeDialogShowing') as bool; } }
2. 在App生命周期中使用
监听AppLifeCycle状态时,通过NativeDialogMonitor判断是否是Native Dialog导致的inactive:
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: const HomePage(), navigatorObservers: [ LifecycleEventHandler( onInactive: () { if (!NativeDialogMonitor().isNativeDialogShowing) { // 处理非Native Dialog触发的inactive状态 print("非Native Dialog导致的App inactive"); } }, ), ], ); } } class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("Native Dialog检测")), body: Center( child: Text("Native Dialog是否显示: ${NativeDialogMonitor().isNativeDialogShowing}"), ), ); } } class LifecycleEventHandler extends NavigatorObserver { final VoidCallback? onInactive; LifecycleEventHandler({this.onInactive}); @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.inactive) { onInactive?.call(); } } }
补充说明
- 如果是第三方库弹出的Native Dialog,需要在原生层做全局监听:Android可通过
Application.ActivityLifecycleCallbacks监听窗口变化,iOS可通过UIWindowSceneDelegate或监听UIWindow的子视图变化来捕获Dialog状态。 - 确保所有Native Dialog的显示/隐藏都调用了对应的状态同步方法,保证状态准确性。
内容的提问来源于stack exchange,提问作者Leonardo Rosa
相关产品推荐
相关产品推荐

