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

Flutter中如何禁用整个屏幕的触摸交互?

实现全局屏幕触摸禁用方案

Flutter的AbsorbPointer、IgnorePointer等组件仅能拦截应用内的触摸事件,要实现系统级全局触摸禁用,必须依赖原生平台的API,通过Flutter的MethodChannel调用原生代码完成。以下分平台给出具体实现步骤:

核心思路

Flutter本身无法突破应用沙盒限制直接拦截系统全局触摸,因此需要:

  1. 在Flutter端通过MethodChannel与原生层通信
  2. 原生层根据平台特性,创建全屏拦截触摸的窗口/视图
  3. 处理平台权限申请(关键,尤其是Android)

Android 实现步骤

1. 申请权限

在android/app/src/main/AndroidManifest.xml中添加悬浮窗权限:

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

2. Flutter端代码

创建工具类封装原生调用:

import 'package:flutter/services.dart';
import 'dart:io' show Platform;
import 'package:url_launcher/url_launcher.dart';

class GlobalTouchController {
  static const MethodChannel _channel = MethodChannel('global_touch_controller');

  /// 检查是否拥有悬浮窗权限(Android)
  static Future<bool> checkOverlayPermission() async {
    if (Platform.isAndroid) {
      return await _channel.invokeMethod<bool>('checkOverlayPermission') ?? false;
    }
    return false;
  }

  /// 跳转至权限设置页(Android)
  static Future<void> requestOverlayPermission() async {
    if (Platform.isAndroid) {
      await launchUrl(Uri.parse('package:${Platform.packageName}'));
    }
  }

  /// 禁用全局触摸
  static Future<void> disableGlobalTouch() async {
    await _channel.invokeMethod('disableGlobalTouch');
  }

  /// 恢复全局触摸
  static Future<void> enableGlobalTouch() async {
    await _channel.invokeMethod('enableGlobalTouch');
  }
}

3. Android原生代码(Kotlin)

修改MainActivity.kt,实现MethodChannel的方法处理:

import android.content.Context
import android.view.View
import android.view.WindowManager
import android.provider.Settings
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private lateinit var windowManager: WindowManager
    private lateinit var touchBlockerView: View
    private val CHANNEL = "global_touch_controller"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
        touchBlockerView = View(this)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "checkOverlayPermission" -> {
                    val hasPermission = Settings.canDrawOverlays(this)
                    result.success(hasPermission)
                }
                "disableGlobalTouch" -> {
                    if (!Settings.canDrawOverlays(this)) {
                        result.error("PERMISSION_DENIED", "需要悬浮窗权限", null)
                        return@setMethodCallHandler
                    }

                    val layoutParams = WindowManager.LayoutParams(
                        WindowManager.LayoutParams.MATCH_PARENT,
                        WindowManager.LayoutParams.MATCH_PARENT,
                        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
                        } else {
                            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
                        },
                        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
                        android.graphics.PixelFormat.TRANSLUCENT
                    )
                    windowManager.addView(touchBlockerView, layoutParams)
                    result.success(null)
                }
                "enableGlobalTouch" -> {
                    if (touchBlockerView.parent != null) {
                        windowManager.removeView(touchBlockerView)
                    }
                    result.success(null)
                }
                else -> result.notImplemented()
            }
        }
    }
}

iOS 实现说明

由于iOS的沙盒限制,普通应用无法直接拦截其他应用的触摸事件,必须通过**辅助功能(Accessibility)**实现,且需要用户手动在「设置-辅助功能」中开启权限:

1. 配置权限描述

在ios/Runner/Info.plist中添加辅助权限说明:

<key>NSAccessibilityUsageDescription</key>
<string>需要全局触摸拦截权限以实现屏幕锁定功能</string>

2. 核心实现思路

  • 使用AXObserver监听系统全局触摸事件,在需要禁用时拦截事件传递
  • 或创建一个全屏的UIWindow,设置windowLevel为UIWindowLevelAlert,覆盖整个屏幕并消费所有触摸事件(仅能拦截本应用内触摸,全局拦截需依赖辅助功能)

注意:iOS的全局触摸拦截实现复杂度高,且受系统权限严格限制,建议仅在必要场景使用。


使用示例

在Flutter页面中调用工具类:

ElevatedButton(
  onPressed: () async {
    bool hasPermission = await GlobalTouchController.checkOverlayPermission();
    if (!hasPermission) {
      await GlobalTouchController.requestOverlayPermission();
      return;
    }
    await GlobalTouchController.disableGlobalTouch();
  },
  child: const Text("禁用全局触摸"),
),
ElevatedButton(
  onPressed: () async {
    await GlobalTouchController.enableGlobalTouch();
  },
  child: const Text("恢复全局触摸"),
),

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 08:54:56