您的位置:首页 > 移动开发

android 焦点获取问题(手机端和TV端)

2016-04-12 17:46 204 查看

/article/4966492.html

Android的Touch Mode

大多数Android设备都是触摸屏的,但是实际上Android设备也支持键盘操作,允许通过键盘来完成导航,点击,输入等。

当用户通过键盘(或者轨迹球)操作的时候,有必要聚焦当前接受输入的UI元素,例如,高亮(聚焦)某个按钮,让用户知道当前正在操作的UI元素是哪个。

但是,当用户使用触摸屏与设备交互的时候,始终聚焦当前UI元素就没有必要了,而且很丑陋;用户点击哪个元素,哪个元素就是当前元素,无需高亮标识。并且,通过触摸屏与设备交互的时候,点击某个UI元素也不会导致该元素聚焦,此时的高亮效果是由Pressed状态来完成的。也就是说,在Touch Mode模式之下,UI元素是不会进入聚焦状态的,即使调用requestFocus也不会。

那个,Android是如何区分这两种情况的呢?

答案就是Touch Mode。当用户开始通过键盘与设备交互的时候,设备就退出Touch Mode模式;当用户开始通过触摸屏与设备交互的时候,设备就进入Touch Mode模式。可以通过调用View的isInTouchMode来判断设备当前是否处于Touch Mode模式。

但是,也有例外情况。有些UI元素,即使是在Touch Mode的状态之下,也需要获得焦点,典型的就是Edittext。那么,这种情况该如何处理呢?

答案就是做特殊处理。Android规定,某些元素,即使是在Touch Mode模式下,也可以获得焦点。调用View的setFocusableInTouchMode(true)可以使View在Touch Mode模式之下仍然可获得焦点(像Edittext就是在内部设置了这个属性),调用isFocusableInTouchMode可以判断View是否可在Touch Mode模式下聚焦。

/article/8532662.html

Android 如何让EditText不自动获取焦点

在项目中,一进入一个页面, EditText默认就会自动获取焦点。

那么如何取消这个默认行为呢?

在网上找了好久,有点 监听软键盘事件,有点 调用 clearFouse()方法,但是测试了都没有! xml中也找不到相应的属性可以关闭这个默认行为

解决之道:在EditText的父级控件中找一个,设置成

android:focusable="true"

android:focusableInTouchMode="true"

这样,就把EditText默认的行为截断了!

<LinearLayout

style="@style/FillWrapWidgetStyle"

android:orientation="vertical"

android:background="@color/black"

android:gravity="center_horizontal"

android:focusable="true"

android:focusableInTouchMode="true"

>

<ImageView

android:id="@+id/logo"

style="@style/WrapContentWidgetStyle"

android:background="@drawable/dream_dictionary_logo"

/>

<RelativeLayout

style="@style/FillWrapWidgetStyle"

android:background="@drawable/searchbar_bg"

android:gravity="center_vertical"

>

<EditText

android:id="@+id/searchEditText"

style="@style/WrapContentWidgetStyle"

android:background="@null"

android:hint="Search"

android:layout_marginLeft="40dp"

android:singleLine="true"

/>

</RelativeLayout>

</LinearLayout>

/article/8374005.html


Android属性 android:focusableInTouchMode

2013-01-11 10:32 15366人阅读 评论(0) 收藏 举报

这个属性的意思很明显,就是可以通过touch来获得focus。在手机上开发用的不多,因为大多手机都是触摸式的。最近一个TV上的应用需要用到。

一个界面上有一个自定义个button,我需要进入这个界面就高亮这个button。但是用遥控选择这个程序进入能正常显示,用鼠标点击进入就没有高亮的效果。最后添加上这个属性,效果出来了。

可见,click事件和touch事件在焦点处理上是不同的。

摘自 厚积而薄发,水到而渠成

http://zhidao.baidu.com/link?url=Kd1MzdC92qEofQlAI2ih2x1xJoDFAd2vIJYwyOOYuCelSUHtxjvHdtv0OirVE5ps37sNSL2CEdakOT3ThAzNzpSqZzw6P4Bjh4LSyeaGEJ_

Android开发中的View类的视图属性focusableInTouchMode这个属性跟focusable有什么区别?

要理解这个属性,首先你得知道,Android不是只面向手机的,它还有可能被安装在电视等非触摸输入设备上.即使是在手机上,目前很多手机也都支持键盘输入了.
focusable这种属性,更多的是为了解决非触摸输入的,因为你用遥控器或键盘点击控件,就必然要涉及到焦点的问题,只有可以获得焦点的控件才能响应键盘或者遥控器或者轨迹球的确定事件.

然后再反过来看focusableInTouchMode.这个属性的意思一如字面所述,就是在进入触摸输入模式后,该控件是否还有获得焦点的能力.
可以简单的理解为,用户一旦开始通过点击屏幕的方式输入,手机就进入了"touch mode".
focusableInTouchMode这种属性,多半是设给EditText这种即使在TouchMode下,依然需要获取焦点的控件.(请自行想下EditText为什么在touch mode下也需要焦点).
比如Button之类的控件,在touch mode下,就已经没有获取焦点的必要了.

有些地方可能表述不太准确,不知道这样说是否可以理解.


追问:

大概理解了。不过你让我猜的那个,我还是有点模糊。。。


追答:

直接讲术语你可能还是不容易理解(主要是我也不太会讲...),咱们想象一下EditText实际的样子.
Android里面EditText是用来接受用户输入的,那问题是在touch mode下我们没键盘,怎么办呢,android会主动给我们弹出一个软键盘出来(或者是手写输入法,这些无所谓...).
那现在想象,我们的界面上有五个这种EditText,那弹出的软键盘的输入,到底要写在哪个EditText上呢?
所以这里就需要焦点来介入了.只有获得了焦点的那个EditText,才能获取软键盘的输入.

这其实就跟你在电脑上输入是一样的场景,你在电脑上输入,会首先用鼠标(或者tab键选取)点击某个输入框,这时候这个输入框就获取焦点了,你再敲键盘的话,输入的字符就会显示在获取焦点的那个输入框里了.




个人总结;

!!!android:focusable 是非touch mode的情况下设定的~

!!!android:focusableInTouchMode 是TouchMode的情况下设定的~(个人测试认为:android:focusableInTouchMode在 非touch mode的情况下也起作用,即:android:focusableInTouchMode包含了Touch Mode和非Touch Mode,意思是即使在Touchmode下也可以发挥作用)

!!!android:focusableInTouchMode和android:focusable 可以截断子控件的获焦行为,所以要根据实际需要,灵活使用

!!!在TouchMode的情况下,手Touch到哪儿,哪儿就可以做出响应,设置的android:focusableInTouchMode或是android:focus感觉好像只适用一个默认用户没有点击行为的情况~

!!!比如在TouchMode的情况下,下面代码中即使父组件设置了android:descendantFocusability="blocksDescendants",在手机屏幕点击事件的话,Button仍然会优先响应click事件,如果把Buttton改为TextView,这一现象将可避免~(猜测这可能是由各控件响应点击事件的默认优先级的原因吧~);如果在非TouchMode的情况下,上面Button优先响应click事件的现象,就不会发生~(仅是由测试demo得出的结论,不清楚深层的代码逻辑)

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:descendantFocusability="blocksDescendants"

android:orientation="horizontal" >

<!-- android:background="@drawable/list_bg_color" -->

<Button

android:id="@+id/btn"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_marginLeft="@dimen/margin_"

android:layout_marginRight="@dimen/margin_"

android:layout_marginTop="@dimen/pading_"

android:textSize="@dimen/btn_size" />

</LinearLayout>

!!! 个人理解:touch mode下,组件响应点击事件可以获取焦点(比如EditText,让用户清楚正在操作的是哪个组件),也可以不获取焦点(比如Button,点击Button的时候,照样可以响应点击事件,点击时高亮显示并不是代表获取焦点,而是由press引发的高亮)

!!!在非touch mode 的情况下,获取不到焦点的控件,无法响应用户的操作行为(如点击事件),即需要先获取到焦点,才可以响应用户操作

!!!总之,手机端和TV端的焦点获得,是有区别的,需要谨慎使用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: