解决 PopupWindow isOutsideTouchable = false 无效问题

问题分析

通常情况下,isOutsideTouchable 设置为 false,意味着当用户点击弹窗外部时,弹窗不应被关闭。然而,在一些场景下,该属性可能不生效,导致点击外部区域时,PopupWindow 仍然会关闭。

首先我们创建popupWindow一般会设置这三个属性

1.popupWindow?.isOutsideTouchable

作用:

• 该属性控制是否允许点击 PopupWindow 以外的区域关闭弹窗。

• 当设置为 true 时,点击弹窗外部的区域,弹窗将会关闭。

• 当设置为 false 时,点击外部区域不会关闭 PopupWindow。

默认值: true,即点击外部会关闭弹窗。

注意: 即便设置为 false,某些设备或场景下仍可能无法完全阻止弹窗关闭。这时需要配合 setTouchInterceptor 进行手动拦截。

2. popupWindow?.isFocusable

作用:

• 控制 PopupWindow 是否可以获得焦点。焦点意味着弹窗能够响应键盘事件(例如返回键)。

• 如果 PopupWindow 获取了焦点,则用户在点击弹窗外部区域时,事件不会传递给其他视图(例如底部的 Activity),而是由弹窗处理。关闭键盘、触摸外部区域等操作时会根据设置来决定是否关闭 PopupWindow。

默认值: false,即 PopupWindow 默认不会获取焦点。

常见用途: 设置为 true 通常用于需要用户进行输入的弹窗(例如弹出的对话框),确保键盘或返回键的事件被弹窗处理。

3. popupWindow?.isTouchable

作用:

• 控制 PopupWindow 是否可以响应触摸事件。

• 设置为 true 时,PopupWindow 可以被触摸,也能和其中的视图进行交互(例如点击按钮)。

• 设置为 false 时,PopupWindow 不会响应任何触摸事件,类似于一个仅显示的视图,用户无法通过触摸进行交互。

默认值: true,即弹窗默认可以响应触摸事件。

但是发现在设置了isOutsideTouchable后,PopupWindow 仍然会关闭,目前isOutsideTouchable 不管true还是false 设置后,点击popupWindow外的区域和点击back键都会关闭,所以如果想要阻止点击popupWindow以外区域关闭,则需要将目前isOutsideTouchable设置为false的同时也要将 isFocusable 设置为false,就比较尴尬,isFocusable设置false后PopupWindow无法获得焦点,那比如我们PopupWindow里面有EditText就会发生无法获取焦点等系列问题


这里使用 setTouchInterceptor允许我们拦截并处理触摸事件。在这里可以通过该方法来手动处理点击事件,确保当 isOutsideTouchable 设置为 false 时,外部的点击不会关闭 PopupWindow。
 

解释

1. setTouchInterceptor:拦截并处理触摸事件。在这个回调中,我们判断是否需要处理点击事件。

2. dispatchTouchEvent:如果 isOutsideTouchable 被设置为 false,我们手动将点击事件分发到 PopupWindow 的内容视图中,以确保点击事件不会关闭 PopupWindow。

3. 返回值:通过返回 popupWindow?.isFocusable == true && popupWindow?.isOutsideTouchable == false,确保在焦点存在且 isOutsideTouchable 为 false 时,拦截外部的点击事件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值