Android touch mode和focusableInTouchMode分析

本文详细介绍了Android设备中touchmode模式的概念及其工作原理,包括触摸屏与UI交互、焦点变化、不同控件的行为差异及如何正确使用该模式。

原文地址:http://www.cnblogs.com/xiaoweiz/p/3833079.html

首先我们来看看touch mode的定义。它是用户和手机进行交互时view层次结构的一个状态。它本身是很容易理解的,

代表了最近一次的交互是否是通过触摸屏发生的,因为在Android设备上还存在别的交互方式,比如D-pad、滚动球等等。

  为什么Android会引入这样一个mode呢?这是因为从交互、设计方面考虑,当用户直接使用keys或trackball与UI

进行交互的时候,必须先使目标控件获得焦点(比如高亮起来),这样用户才会注意到是什么控件在接收输入。然而如果

设备支持触摸手势的话,用户直接用手指点击控件,这个时候当然就没必要将目标控件高亮了(即获取焦点)。

  对于一个拥有触摸屏功能的设备而言, 一旦用户用手点击屏幕, 设备会立刻进入touch mode。这时候被点击的控件

只有isFocusableInTouchMode()为true的时候才会获得focus,比如EditText控件。其他可以触摸的控件比如Button

(其isFocusableInTouchMode默认为false), 当被点击的时候不会获取焦点,它们只是简单地执行onClick事件而已。

  任何时候只要用户点击key或滚动trackball, 设备就会退出touch mode,并且找一个view将焦点置于其上,这样用户

可以在不需要再次触摸屏幕的情况下接着和UI进行交互。touch mode在整个系统运行期间都是有效的(跨activities),任何

时候都可以调用View.isInTouchMode()方法来查看当前设备是否处于touch mode状态。

  从上面的介绍我们能看出来,在触摸屏下的view,设置了focusableInTouchMode和没设置在用户体验上是不同的,

其实内部的处理逻辑也是不同的,比如:没设置这个属性的控件在用户触摸交互时是不会获得focus的,也就是说focus在

touch过程中是不会改变的,只是其onClickListener如果设置了的话会在up事件到来时触发。而如果设置了focusableInTouchMode

属性的话,它的行为是首先尝试获得focus,如果获得成功的话其onClickListener是不会触发的,只有当你第2次再点击它时,

才会执行onClickListener。可能有些同学在开发中也遇到过这个问题,stackoverflow上有一个同样的问题:

http://stackoverflow.com/questions/20473355/button-is-not-calling-onclicklistener-with-first-click?lq=1,

大家可以参考下。由于设置了这个属性后会引起和android正常交互行为的不一致,所以android建议我们保守地使用这个属性,

在你确定要用它之前最好三思而后行,并且确保你自己看过Android developers blog里关于touch mode介绍的文章:

http://android-developers.blogspot.com/2008/12/touch-mode.html

  关于设置了这个属性后行为不一致的问题,我们在后面touch事件的处理过程中还会再次提到,那时我们就可以从源码

的角度来看看原因了。

Android TV应用中,为了支持用户通过遥控器先选中Button再按下“OK”键触发操作,同时兼容鼠标的点击直接执行功能,可以按照以下设计思路: ### 设计步骤 1. **设置焦点管理** - 确保所有UI控件都可以获得焦点 (focusable)。对于Button等交互组件,默认已经具备此特性。 - 使用`android:focusable="true"` `android:focusableInTouchMode="true"` 来明确指定哪些视图可以获得焦点。 2. **处理方向按键事件** 当用户使用遥控器的方向键选择按钮时,系统会自动调整焦点到相应的View,并高亮显示当前聚焦的控件(如改变背景颜色)。这通常无需额外编码即可实现。 3. **监听确认键动作** 捕获遥控器上的"OK"/Enter按键事件以激活选定按钮的功能。可以在Activity或者Fragment层级覆盖onKeyDown/onKeyUp方法检测特定按键代码;也可以给目标Button绑定OnClickListener作为更简单的方案之一。 4. **适配鼠标输入设备** 对于连接了鼠标的场景,则不需要等待元素处于焦点状态就可以立刻响应左键单击的动作。这是由系统的触摸模式(touch mode)机制自动完成切换的结果——一旦检测到来自非导航控制器(例如触屏、蓝牙键盘等) 的互动信号,便会进入touch-mode下运行程序逻辑链路。 5. **优化用户体验细节** * 调整Focus Highlight样式让当前活动项更加醒目直观; * 根据实际需求设定长按快捷选项等功能提升效率; * 测试多种品牌型号电视及外设组合验证一致性表现。 ### 示例代码片段 ```java @Override public boolean onKeyDown(int keyCode, KeyEvent event){ if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER ){ Button myBtn = findViewById(R.id.my_button); myBtn.performClick(); //模拟普通点按效果 return true; } return super.onKeyDown(keyCode,event); } //或者单独为某个按钮配置listener myButton.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ Toast.makeText(getApplicationContext(),"You pressed OK!",Toast.LENGTH_SHORT).show(); } }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值