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

Android 11/12中如何让悬浮图片穿透触摸事件?

解决Android 11/12悬浮窗触摸穿透问题

针对Android 11和12版本中悬浮图片无法让触摸事件穿透到底层的问题,可通过以下代码修改解决:

1. 补充WindowManager.LayoutParams的Flags

在原有flags基础上添加WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,该标记会让悬浮窗完全不接收触摸事件,直接将事件传递给底层界面。修改后的flags定义如下:

val flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
        WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
        WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE

2. 明确禁用视图的触摸交互能力

在Android 11/12的系统逻辑下,明确设置视图的交互属性可避免系统默认的触摸拦截。创建overlayView时补充以下配置:

val overlayView = ImageView(this).apply {
    // 禁用视图的触摸、焦点能力
    isClickable = false
    isFocusable = false
    isFocusableInTouchMode = false
    // 保留原有Glide加载代码
    Glide.with(this@BrokenServiceClass)
        .load(imageUri)
        .into(this)
}

3. 移除冗余触摸监听

既然已通过flags和视图属性禁用了触摸事件接收,原有的touchInterceptor触摸监听可直接移除,减少不必要的代码。

修改后的完整函数

private fun showImageOverlay(imageUri: Uri) {
    removeImageOverlay()

    val type: Int = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
        WindowManager.LayoutParams.TYPE_SYSTEM_ALERT
    } else {
        WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
    }

    val flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
            WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE

    val layoutParams = WindowManager.LayoutParams(
        WindowManager.LayoutParams.MATCH_PARENT,
        WindowManager.LayoutParams.MATCH_PARENT,
        type,
        flags,
        PixelFormat.TRANSLUCENT
    )

    val overlayView = ImageView(this).apply {
        isClickable = false
        isFocusable = false
        isFocusableInTouchMode = false
        Glide.with(this@BrokenServiceClass)
            .load(imageUri)
            .into(this)
    }

    windowManager?.addView(overlayView, layoutParams)

    overlayView.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
        override fun onViewAttachedToWindow(v: View) {
            // 视图附加逻辑保留
        }

        override fun onViewDetachedFromWindow(v: View) {
            removeImageOverlay()
        }
    })
}

原理说明

Android 11(API 30)和12(API 31)对TYPE_APPLICATION_OVERLAY类型窗口的触摸事件处理逻辑做了调整,仅设置FLAG_NOT_FOCUSABLE不足以让事件完全穿透,必须配合FLAG_NOT_TOUCHABLE标记,同时明确禁用视图交互能力,才能确保触摸事件顺利传递到底层界面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 15:28:22