TV按键拦截问题

本文探讨了在Android中遇到的一个按键分发问题,当快速输入密码并切换View时,按键事件被错误地分配给当前View而非预期的下一级View。文章详细分析了问题原因,并提供了三种解决方案,包括优化加载速度、预加载下一级View和使用全局变量控制按键响应。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Bug描述(原谅缺少一张图)

对象:当前View、下一级View、遥控板按键、密码输入框。
操作:在当前View,使用按遥控键OK进入密码输入框,正确输入密码,点击OK后立马按下键(此时下一级View还未加载出来)。
结果:此时当前View响应下键(下移一项),焦点在下一级View(此时下一级View已未加载出来)。
频率:30%
原因:下一级View布局、渲染等需要时间,所以此时按遥控键,下一级View并不能接收到按键事件,于是当前View接收按键并消费了。
其实,严格来说,这是Android的按键分发问题。本应该分发到下一级,却误分发给了当前View。
解决:有如下3种方式可尝试(ps:我是用第3种方式解决问题的)

解决方法一

方式:优化下一级View的加载

既然问题出在下一级View未显示,而此时又来了按键事件(ps:按键响应和加载View,它们是异步进行的),导致下一级View无法响应按键事件。那么首先想到的就是:缩短下一级View的加载时间,减少中间的空档期。

评价:这种方式,得看自己View加载的耗时以及渲染优化等。

解决方法二

方式:预加载下一级View

当前View加载密码输入框时,同时加载下一级View。

评价:这种方式需要将下一级View分解成加载、显示和释放等。(1)下一级View的显示速度快了些,但是依旧存在当前View接收按键并消费了的情况,只是Bug发生频率有所下降,是一种优化的可行方式。(2)如果密码输入框之后不显示下一级View,此时的预加载就得注意内存释放等问题了,小心memory leak。

解决方法三

方法3.1

方式:150ms内取消按键响应

因为,这是用户操作过快导致的概率性Bug,一般我们可以,在一定时间内取消用户的操作。

评价:这得视项目情况而定。

方法3.2

方式:设置应用全局变量(默认false),离开当前View时就不再接收按键响应,重新回到当前View时继续接收按键响应。

1、密码输入框正确输入密码时,会加载下一级View,此时设置全局变量为true,当下一级View加载好并获得焦点时将全局变量设为false。

2、重写当前View的dispatchKeyEvent(),在首行判断该全局变量如果为true,就返回true(表示当前View已消费该事件,不再向下传递);全局变量如果为false,就返回false(不拦截事件,继续向下传递)。

这是最正常的逻辑,这正所谓:你走,我不送你;你来,即使风再大雨再大,我,都要去接你。

代码实现:只在四处添加,分别是:声明变量为false、复位false、离开当前View时设为true、dispatchKeyEvent()判断是否去消费该按键(ps:Kotlin实现)

var isEnterNextView: Boolean = false // 声明变量为false

override fun onDismissPopView(level: Int) { // 复位
        Log.d(TAG, "onDismissPopView")
        isEnterListPopView = false // 每次从下级——ListPopView返回时,会触发此回调。

SettingWidgetManager.showPasswordDialog(mContext1, object : SettingWidgetManager.PasswordDialogCallBack {
    override fun correct() {
        isEnterNextView= true // 离开当前View时设为true
        view.showPopView(baseVm.getPopViewType(), mViewLevel, this@SettingView)

override fun dispatchKeyEvent(event: KeyEvent): Boolean {
    if(isEnterNextView) return true // 如果进入了下级View,此时还能收到事件响应的话,就应抛弃该事件。

评价:会丢失按键响应(因为当前View已拦截,下一级View还未加载完成),Bug未出时不关注此逻辑,Bug来时漫山遍野寻找灵丹妙药。原来,初恋才是最好,陪伴才是最长情的告白。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值