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

Flutter iOS:如何监听状态栏点击事件并调用自定义方法?

监听iOS状态栏点击事件并传递到Flutter的实现方案

方案一:原生iOS侧监听+MethodChannel传递(可行方案)

1. iOS原生代码修改

iOS没有直接暴露状态栏点击的回调API,需要通过监听全局触摸事件判断点击区域是否属于状态栏,再通过MethodChannel把事件传递到Flutter层。

在AppDelegate.swift中做如下修改:

import Flutter
import UIKit

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    private var statusBarChannel: FlutterMethodChannel?
    
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        // 初始化MethodChannel,名称两端要和Flutter侧保持一致
        statusBarChannel = FlutterMethodChannel(name: "com.app/statusBarTap", binaryMessenger: controller.binaryMessenger)
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
    
    // 监听全局触摸事件
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
        guard let touch = touches.first else { return }
        // 适配iOS 13+的状态栏区域获取
        let statusBarFrame: CGRect
        if #available(iOS 13.0, *) {
            statusBarFrame = UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame ?? .zero
        } else {
            statusBarFrame = UIApplication.shared.statusBarFrame
        }
        // 判断点击位置是否在状态栏内
        if statusBarFrame.contains(touch.location(in: window)) {
            statusBarChannel?.invokeMethod("statusBarTapped", arguments: nil)
        }
    }
}

2. Flutter Dart侧接收事件并处理

在Flutter页面中初始化MethodChannel,监听原生传递的事件,触发自定义方法:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class StatusBarTapDemo extends StatefulWidget {
  const StatusBarTapDemo({super.key});

  @override
  State<StatusBarTapDemo> createState() => _StatusBarTapDemoState();
}

class _StatusBarTapDemoState extends State<StatusBarTapDemo> {
  late MethodChannel _statusBarChannel;
  final GlobalKey _targetScrollKey = GlobalKey();

  @override
  void initState() {
    super.initState();
    // 与原生端一致的Channel名称
    _statusBarChannel = const MethodChannel('com.app/statusBarTap');
    // 注册方法回调
    _statusBarChannel.setMethodCallHandler((call) async {
      if (call.method == 'statusBarTapped') {
        // 调用自定义方法,比如滚动到指定组件位置
        await Scrollable.ensureVisible(
          _targetScrollKey.currentContext!,
          duration: const Duration(milliseconds: 300),
          curve: Curves.easeInOut,
        );
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        itemCount: 100,
        itemBuilder: (context, index) {
          return ListTile(
            key: index == 99 ? _targetScrollKey : null,
            title: Text('列表项 $index'),
          );
        },
      ),
    );
  }
}

方案二:Flutter端直接监听(暂不可行)

目前Flutter框架没有提供直接监听iOS状态栏点击事件的官方API,无法通过纯Dart代码实现该需求,只能依赖原生桥接方案。

注意事项

  • 确保MethodChannel的名称在iOS和Flutter端完全一致,否则无法通信
  • 如果项目使用了iOS 13及以上系统,必须适配状态栏区域的获取逻辑,避免出现判断错误
  • Android端无需额外处理,系统默认会在点击状态栏时触发页面滚动到顶部

内容的提问来源于stack exchange,提问作者Alex Ivashkin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 14:35:13