You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 10:11:07