You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter实现全局半透明可穿透悬浮层的方法咨询

用Flutter实现全局半透明可穿透悬浮图层

咱先明确:完全可以做到!核心要搞定俩事儿:悬浮窗权限申请点击穿透的配置,而且得区分Android和iOS平台来搞——毕竟俩系统的权限机制差不少,我给你一步步拆解:

Android 平台实现步骤

1. 申请悬浮窗权限

首先得在android/app/src/main/AndroidManifest.xml里添加系统悬浮窗权限:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

Android 6.0及以上还得动态申请权限,推荐用permission_handler插件来处理,代码大概是这样:

import 'package:permission_handler/permission_handler.dart';

Future<bool> requestOverlayPerm() async {
  final status = await Permission.systemAlertWindow.request();
  // 有些国产ROM可能弹不出系统权限框,得引导用户去设置页手动开启
  if (status.isDenied) {
    await openAppSettings();
  }
  return status.isGranted;
}

2. 创建可穿透的悬浮窗

flutter_overlay_window这类专门做悬浮窗的插件会省很多事儿,初始化时要重点配置点击穿透的标记

import 'package:flutter_overlay_window/flutter_overlay_window.dart';

Future<void> showTransparentOverlay() async {
  final hasPerm = await requestOverlayPerm();
  if (!hasPerm) return;

  await FlutterOverlayWindow.initialize();
  // 显示全屏半透明悬浮层
  await FlutterOverlayWindow.showOverlay(
    width: MediaQuery.of(context).size.width,
    height: MediaQuery.of(context).size.height,
    alignment: OverlayAlignment.center,
    // 关键参数:notTouchModal 让触摸事件穿透到下层应用
    flag: OverlayFlag.notTouchModal,
    overlayContent: Container(
      color: Colors.blue.withOpacity(0.2), // 自定义半透明颜色
      // 如果你想让悬浮层上某块区域可点击,就用GestureDetector包裹该区域,其他区域自动穿透
      child: Center(
        child: GestureDetector(
          onTap: () => print("悬浮层按钮被点击"),
          child: Container(
            width: 100,
            height: 100,
            color: Colors.red.withOpacity(0.5),
          ),
        ),
      ),
    ),
  );
}

原理是底层给Android Window设置了FLAG_NOT_TOUCH_MODALFLAG_NOT_FOCUSABLE标记,这样系统会把未被悬浮层消费的触摸事件传递给下层应用。

iOS 平台实现说明

iOS的系统限制比Android严很多,全局悬浮(跨应用)只有辅助功能类应用能通过审核,其他场景App Store大概率拒审。如果是做自己App内的悬浮层,那简单很多;如果要全局悬浮,得这么搞:

1. 开启辅助功能权限

需要在Info.plist里添加辅助功能相关配置,引导用户去系统设置的「辅助功能」里开启你的App权限,推荐用flutter_accessibility_service插件来处理权限申请。

2. 实现可穿透悬浮层

iOS里要让视图穿透点击,只需设置userInteractionEnabled = false,Flutter层面就是确保你的悬浮层UI没有消费触摸事件(比如不用GestureDetector包裹整个层)。如果用原生混合开发,你需要在UIWindow或者UIView上设置这个属性,再把Flutter视图嵌进去。

⚠️ 注意:iOS全局悬浮的审核门槛很高,必须是真正的辅助工具(比如屏幕阅读器、触控增强工具),普通应用别轻易尝试,否则过不了审。

通用注意事项

  • Flutter层的UI要设置全透明背景:在Scaffold里设backgroundColor: Colors.transparent,同时MaterialApptheme里也要把scaffoldBackgroundColor设为透明。
  • 如果悬浮层不需要交互,别在Flutter里加任何手势监听,这样触摸事件会完全穿透到下层应用。

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

火山引擎 最新活动