参考地址:http://blog.csdn.net/zhangxu365/article/details/7050251
今天解决了一个Android平台下的焦点问题。发现其中关键问题的所在是Android的touchMode。从JavaSwing平台过来的人,都会关注setFocusable()和requestFocus()方法,但是在Android的View中还有另外的两个个方法,setFocusableInTouchMode()和requestFocusFromTouch()方法。这个两个方法就是解决Android上的焦点获取问题的关键。
同时在View类中,还有一个isInTouchMode(),可以帮助我们在监听Focuse事件时判断是否执行click(). 代码如下:
复制到剪贴板 XML/HTML代码
ImageButton.OnFocusChangeListener mFocusChangeListener = new ImageButton.OnFocusChangeListener(){
public void onFocusChange(View v, boolean hasFocus) {
Log.d("FocuseChange", "Focuse has changed.");
if (hasFocus) {
// 如果是touchmode就执行click,否则就会只是选中。
v.setBackgroundDrawable(getResources().getDrawable(R.drawable.));
if (v.isInTouchMode()){
((ImageButton)v).performClick();
}
} else {
v.setBackgroundDrawable(getResources().getDrawable(R.));
v.getBackground().setAlpha(100);
}
}
};
系统框架将处理日常的焦点移动来响应用户的输入,它包刮改变焦点(当界面是被移除,隐藏,或者作为一个新的View变为可用状态),通过isFocusable()这个方法我们可以知道view是否具有接受焦点的资格,也可以通过setFocusable().来设置view接受焦点的资格,对应在触摸模式下,你可以调用isFocusableInTouchMode().来获知是否有焦点来响应点触,也可以通过setFocusableInTouchMode().来设置是否有焦点来响应点触的资格.
系统框架控制焦点移动到另一个组件的算法是在某一方向上邻近的组件,在极个别情况下,默认的算法可能不符合开发者的预想要求,在这种情况下,你可以覆写下列XML属性的布局文件:nextFocusDown ,nextFocusLeft ,nextFocusRight ,和nextFocusUp设置他们的值来明确焦点从当前界面移动下个界面的Id。例如:
<LinearLayout
android:orientation="vertical"
... >
<Button android:id="@+id/top"
android:nextFocusUp="@+id/bottom"
... />
<Button android:id="@+id/bottom"
android:nextFocusDown="@+id/top"
... />
</LinearLayout>
一般来说,在这个垂直布局,浏览的焦点会从第一个按钮开始,不会是从第二个或者其他的,现在topButtont已经通过nextFocusUp (反之亦然)确定了bottom.
通常如果你想宣布用户界面具有焦点的资格 (如果这个界面在传统上是没有的),可以在xml布局里去加上的android:focusable的属性,并设置它的值,您也可以宣布在触摸模式下具有焦点的资格,同样也只在xml里添android:focusableInTouchMode.的属性,并设置它的值. 当用户请求在某个界面聚集焦点时,会调用requestFocus().这个方法。监听到焦点活动(获得焦点或失去焦点都会被通知),会调用onFocusChange(),这个方法。虽然帖子比较短,但是我感觉这个例子还是非常有用的,希望对开发者有一些帮助。想继续交流的可以回帖。
步骤3 创建自定义的控件焦点顺序
下面,我们尝试创建自定义的控件焦点顺序,即同时允许在上面的界面中,当用户按键时,以顺时针或逆时针进行控件切换,如下图:
也就是说,允许用户当按“Down”或“Right”键时,切换顺序是顺时针方向,比如假设当前在键12上,按“Down”或“Right”键时,会切换到键1,而按“Up”或”Left”时,会切换到键11,如此类推。要实现这点,可以在每个按钮中进行设置如下四个属性:
android:nextFocusUp- 定义当点up键时,哪个控件将获得焦点
android:nextFocusDown-定义当点down键时,哪个控件将获得焦点
android:nextFocusLeft-定义当点left键时,哪个控件将获得焦点
android:nextFocusRight--定义当点right键时,哪个控件将获得焦点
下面是其代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
style="@style/clockFaceNum"
android:text="12"
android:id="@+id/button12"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:nextFocusUp="@+id/button11"
android:nextFocusLeft="@+id/button11"
android:nextFocusRight="@+id/button1"
android:nextFocusDown="@+id/button1">
</Button>
<Button
style="@style/clockFaceNum"
android:text="11"
android:id="@+id/button11"
android:layout_below="@+id/button12"
android:layout_toLeftOf="@+id/button12"
android:nextFocusUp="@+id/button10"
android:nextFocusLeft="@+id/button10"
android:nextFocusRight="@+id/button12"
android:nextFocusDown="@+id/button12">
</Button>
<Button
style="@style/clockFaceNum"
android:text="1"
android:id="@+id/button1"
android:layout_below="@+id/button12"
android:layout_toRightOf="@+id/button12"
android:nextFocusUp="@+id/button12"
android:nextFocusLeft="@+id/button12"
android:nextFocusRight="@+id/button2"
android:nextFocusDown="@+id/button2">
</Button>
<Button
style="@style/clockFaceNum"
android:text="10"
android:id="@+id/button10"
android:layout_below="@+id/button11"
android:layout_toLeftOf="@+id/button11"
android:nextFocusUp="@+id/button9"
android:nextFocusLeft="@+id/button9"
android:nextFocusRight="@+id/button11"
android:nextFocusDown="@+id/button11">
</Button>
<Button
style="@style/clockFaceNum"
android:text="2"
android:id="@+id/button2"
android:layout_below="@+id/button1"
android:layout_toRightOf="@+id/button1"
android:nextFocusUp="@+id/button1"
android:nextFocusLeft="@+id/button1"
android:nextFocusRight="@+id/button3"
android:nextFocusDown="@+id/button3">
</Button>
<Button
style="@style/clockFaceNum"
android:text="9"
android:id="@+id/button9"
android:layout_below="@+id/button10"
android:layout_toLeftOf="@+id/button10"
android:nextFocusUp="@+id/button8"
android:nextFocusLeft="@+id/button8"
android:nextFocusRight="@+id/button10"
android:nextFocusDown="@+id/button10">
</Button>
<Button
style="@style/clockFaceNum"
android:text="3"
android:id="@+id/button3"
android:layout_below="@+id/button2"
android:layout_toRightOf="@+id/button2"
android:nextFocusUp="@+id/button2"
android:nextFocusLeft="@+id/button2"
android:nextFocusRight="@+id/button4"
android:nextFocusDown="@+id/button4">
</Button>
<Button
style="@style/clockFaceNum"
android:text="8"
android:id="@+id/button8"
android:layout_below="@+id/button9"
android:layout_toRightOf="@+id/button9"
android:nextFocusUp="@+id/button7"
android:nextFocusLeft="@+id/button7"
android:nextFocusRight="@+id/button9"
android:nextFocusDown="@+id/button9">
</Button>
<Button
style="@style/clockFaceNum"
android:text="4"
android:id="@+id/button4"
android:layout_below="@+id/button3"
android:layout_toLeftOf="@+id/button3"
android:nextFocusUp="@+id/button3"
android:nextFocusLeft="@+id/button3"
android:nextFocusRight="@+id/button5"
android:nextFocusDown="@+id/button5">
</Button>
<Button
style="@style/clockFaceNum"
android:text="7"
android:id="@+id/button7"
android:layout_below="@+id/button8"
android:layout_toRightOf="@+id/button8"
android:nextFocusUp="@+id/button6"
android:nextFocusLeft="@+id/button6"
android:nextFocusRight="@+id/button8"
android:nextFocusDown="@+id/button8">
</Button>
<Button
style="@style/clockFaceNum"
android:text="5"
android:id="@+id/button5"
android:layout_below="@+id/button4"
android:layout_toLeftOf="@+id/button4"
android:nextFocusUp="@+id/button4"
android:nextFocusLeft="@+id/button4"
android:nextFocusRight="@+id/button6"
android:nextFocusDown="@+id/button6">
</Button>
<Button
style="@style/clockFaceNum"
android:text="6"
android:id="@+id/button6"
android:layout_below="@+id/button5"
android:layout_centerHorizontal="true"
android:nextFocusUp="@+id/button5"
android:nextFocusLeft="@+id/button5"
android:nextFocusRight="@+id/button7"
android:nextFocusDown="@+id/button7">
</Button>
</RelativeLayout>
下图中是假定在键12开始按down键时的焦点切换顺序:
步骤4 设置界面的初始控件焦点
在每个页面加载时,可以设置界面中初始的控件焦点,以方便用户的定位操作,只需要在控件中加入即可。比如:
<Button
style="@style/clockFaceNum"
android:text="12"
android:id="@+id/button12"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:nextFocusUp="@+id/button11"
android:nextFocusLeft="@+id/button11"
android:nextFocusRight="@+id/button1"
android:nextFocusDown="@+id/button1">
<requestFocus />
</Button>
小结
作为开发者,一定要记住由于Android设备的多样性,用户如何在界面上方便地进行输入或在不同的控件中来回切换是十分重要的,本文简单介绍了用户如何自定义控件的焦点切换顺序,这对于用户界面的体验是很有好处的。
项目实践:
界面中有多个view的时候,按上下左右键 经常找不到 焦点在哪里,解决方法是把所有的view 先 setFocus(false), 然后再把想获取焦点的view.setFocus(ture)
再 view.requestFocus();
今天解决了一个Android平台下的焦点问题。发现其中关键问题的所在是Android的touchMode。从JavaSwing平台过来的人,都会关注setFocusable()和requestFocus()方法,但是在Android的View中还有另外的两个个方法,setFocusableInTouchMode()和requestFocusFromTouch()方法。这个两个方法就是解决Android上的焦点获取问题的关键。
同时在View类中,还有一个isInTouchMode(),可以帮助我们在监听Focuse事件时判断是否执行click(). 代码如下:
复制到剪贴板 XML/HTML代码
ImageButton.OnFocusChangeListener mFocusChangeListener = new ImageButton.OnFocusChangeListener(){
public void onFocusChange(View v, boolean hasFocus) {
Log.d("FocuseChange", "Focuse has changed.");
if (hasFocus) {
// 如果是touchmode就执行click,否则就会只是选中。
v.setBackgroundDrawable(getResources().getDrawable(R.drawable.));
if (v.isInTouchMode()){
((ImageButton)v).performClick();
}
} else {
v.setBackgroundDrawable(getResources().getDrawable(R.));
v.getBackground().setAlpha(100);
}
}
};
系统框架将处理日常的焦点移动来响应用户的输入,它包刮改变焦点(当界面是被移除,隐藏,或者作为一个新的View变为可用状态),通过isFocusable()这个方法我们可以知道view是否具有接受焦点的资格,也可以通过setFocusable().来设置view接受焦点的资格,对应在触摸模式下,你可以调用isFocusableInTouchMode().来获知是否有焦点来响应点触,也可以通过setFocusableInTouchMode().来设置是否有焦点来响应点触的资格.
系统框架控制焦点移动到另一个组件的算法是在某一方向上邻近的组件,在极个别情况下,默认的算法可能不符合开发者的预想要求,在这种情况下,你可以覆写下列XML属性的布局文件:nextFocusDown ,nextFocusLeft ,nextFocusRight ,和nextFocusUp设置他们的值来明确焦点从当前界面移动下个界面的Id。例如:
<LinearLayout
android:orientation="vertical"
... >
<Button android:id="@+id/top"
android:nextFocusUp="@+id/bottom"
... />
<Button android:id="@+id/bottom"
android:nextFocusDown="@+id/top"
... />
</LinearLayout>
一般来说,在这个垂直布局,浏览的焦点会从第一个按钮开始,不会是从第二个或者其他的,现在topButtont已经通过nextFocusUp (反之亦然)确定了bottom.
通常如果你想宣布用户界面具有焦点的资格 (如果这个界面在传统上是没有的),可以在xml布局里去加上的android:focusable的属性,并设置它的值,您也可以宣布在触摸模式下具有焦点的资格,同样也只在xml里添android:focusableInTouchMode.的属性,并设置它的值. 当用户请求在某个界面聚集焦点时,会调用requestFocus().这个方法。监听到焦点活动(获得焦点或失去焦点都会被通知),会调用onFocusChange(),这个方法。虽然帖子比较短,但是我感觉这个例子还是非常有用的,希望对开发者有一些帮助。想继续交流的可以回帖。
步骤3 创建自定义的控件焦点顺序
下面,我们尝试创建自定义的控件焦点顺序,即同时允许在上面的界面中,当用户按键时,以顺时针或逆时针进行控件切换,如下图:
也就是说,允许用户当按“Down”或“Right”键时,切换顺序是顺时针方向,比如假设当前在键12上,按“Down”或“Right”键时,会切换到键1,而按“Up”或”Left”时,会切换到键11,如此类推。要实现这点,可以在每个按钮中进行设置如下四个属性:
android:nextFocusUp- 定义当点up键时,哪个控件将获得焦点
android:nextFocusDown-定义当点down键时,哪个控件将获得焦点
android:nextFocusLeft-定义当点left键时,哪个控件将获得焦点
android:nextFocusRight--定义当点right键时,哪个控件将获得焦点
下面是其代码:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
style="@style/clockFaceNum"
android:text="12"
android:id="@+id/button12"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:nextFocusUp="@+id/button11"
android:nextFocusLeft="@+id/button11"
android:nextFocusRight="@+id/button1"
android:nextFocusDown="@+id/button1">
</Button>
<Button
style="@style/clockFaceNum"
android:text="11"
android:id="@+id/button11"
android:layout_below="@+id/button12"
android:layout_toLeftOf="@+id/button12"
android:nextFocusUp="@+id/button10"
android:nextFocusLeft="@+id/button10"
android:nextFocusRight="@+id/button12"
android:nextFocusDown="@+id/button12">
</Button>
<Button
style="@style/clockFaceNum"
android:text="1"
android:id="@+id/button1"
android:layout_below="@+id/button12"
android:layout_toRightOf="@+id/button12"
android:nextFocusUp="@+id/button12"
android:nextFocusLeft="@+id/button12"
android:nextFocusRight="@+id/button2"
android:nextFocusDown="@+id/button2">
</Button>
<Button
style="@style/clockFaceNum"
android:text="10"
android:id="@+id/button10"
android:layout_below="@+id/button11"
android:layout_toLeftOf="@+id/button11"
android:nextFocusUp="@+id/button9"
android:nextFocusLeft="@+id/button9"
android:nextFocusRight="@+id/button11"
android:nextFocusDown="@+id/button11">
</Button>
<Button
style="@style/clockFaceNum"
android:text="2"
android:id="@+id/button2"
android:layout_below="@+id/button1"
android:layout_toRightOf="@+id/button1"
android:nextFocusUp="@+id/button1"
android:nextFocusLeft="@+id/button1"
android:nextFocusRight="@+id/button3"
android:nextFocusDown="@+id/button3">
</Button>
<Button
style="@style/clockFaceNum"
android:text="9"
android:id="@+id/button9"
android:layout_below="@+id/button10"
android:layout_toLeftOf="@+id/button10"
android:nextFocusUp="@+id/button8"
android:nextFocusLeft="@+id/button8"
android:nextFocusRight="@+id/button10"
android:nextFocusDown="@+id/button10">
</Button>
<Button
style="@style/clockFaceNum"
android:text="3"
android:id="@+id/button3"
android:layout_below="@+id/button2"
android:layout_toRightOf="@+id/button2"
android:nextFocusUp="@+id/button2"
android:nextFocusLeft="@+id/button2"
android:nextFocusRight="@+id/button4"
android:nextFocusDown="@+id/button4">
</Button>
<Button
style="@style/clockFaceNum"
android:text="8"
android:id="@+id/button8"
android:layout_below="@+id/button9"
android:layout_toRightOf="@+id/button9"
android:nextFocusUp="@+id/button7"
android:nextFocusLeft="@+id/button7"
android:nextFocusRight="@+id/button9"
android:nextFocusDown="@+id/button9">
</Button>
<Button
style="@style/clockFaceNum"
android:text="4"
android:id="@+id/button4"
android:layout_below="@+id/button3"
android:layout_toLeftOf="@+id/button3"
android:nextFocusUp="@+id/button3"
android:nextFocusLeft="@+id/button3"
android:nextFocusRight="@+id/button5"
android:nextFocusDown="@+id/button5">
</Button>
<Button
style="@style/clockFaceNum"
android:text="7"
android:id="@+id/button7"
android:layout_below="@+id/button8"
android:layout_toRightOf="@+id/button8"
android:nextFocusUp="@+id/button6"
android:nextFocusLeft="@+id/button6"
android:nextFocusRight="@+id/button8"
android:nextFocusDown="@+id/button8">
</Button>
<Button
style="@style/clockFaceNum"
android:text="5"
android:id="@+id/button5"
android:layout_below="@+id/button4"
android:layout_toLeftOf="@+id/button4"
android:nextFocusUp="@+id/button4"
android:nextFocusLeft="@+id/button4"
android:nextFocusRight="@+id/button6"
android:nextFocusDown="@+id/button6">
</Button>
<Button
style="@style/clockFaceNum"
android:text="6"
android:id="@+id/button6"
android:layout_below="@+id/button5"
android:layout_centerHorizontal="true"
android:nextFocusUp="@+id/button5"
android:nextFocusLeft="@+id/button5"
android:nextFocusRight="@+id/button7"
android:nextFocusDown="@+id/button7">
</Button>
</RelativeLayout>
下图中是假定在键12开始按down键时的焦点切换顺序:
步骤4 设置界面的初始控件焦点
在每个页面加载时,可以设置界面中初始的控件焦点,以方便用户的定位操作,只需要在控件中加入即可。比如:
<Button
style="@style/clockFaceNum"
android:text="12"
android:id="@+id/button12"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:nextFocusUp="@+id/button11"
android:nextFocusLeft="@+id/button11"
android:nextFocusRight="@+id/button1"
android:nextFocusDown="@+id/button1">
<requestFocus />
</Button>
小结
作为开发者,一定要记住由于Android设备的多样性,用户如何在界面上方便地进行输入或在不同的控件中来回切换是十分重要的,本文简单介绍了用户如何自定义控件的焦点切换顺序,这对于用户界面的体验是很有好处的。
项目实践:
界面中有多个view的时候,按上下左右键 经常找不到 焦点在哪里,解决方法是把所有的view 先 setFocus(false), 然后再把想获取焦点的view.setFocus(ture)
再 view.requestFocus();
发表评论
-
代码混淆
2013-05-18 14:31 791代码混淆: http://wenku.baidu.com/ ... -
apk签名方法
2012-12-17 14:36 816签名证书,方式相同包名的不同apk互相覆盖安装。 1. ... -
Ubuntu安装Android开发环境
2012-11-17 00:38 16721、JDK安装 在下载JDK,官网地址为:http://ww ... -
Android之完美退出所有activity方法
2012-07-10 18:52 1029/*还有一种比较流行的Android经典完美退出方法,使用单例 ... -
Android报表工具
2012-05-11 16:11 1339Android报表工具下载地址:http://code.goo ... -
Android 推送
2012-04-01 13:44 1345关于服务器端向Android客户端的推送,主要有三种方 ... -
HttpClient 教程 (六)
2012-03-21 13:26 801HttpClient 教程 (六) 第六章 高级主题 6.1 ... -
HttpClient 教程 (五)
2012-03-21 13:26 861第五章 HTTP客户端服务 5.1 HttpClient门 ... -
HttpClient 教程 (四)
2012-03-21 13:26 1023第四章 HTTP认证 HttpClient ... -
HttpClient 教程 (三)
2012-03-21 13:26 1222HttpClient 教程 (三) 第三章 HTTP状态管理 ... -
HttpClient 教程 (二)
2012-03-20 15:48 1017HttpClient 教程 (二) 第二章 连接管理 Htt ... -
HttpClient 教程 (一)
2012-03-20 15:47 956HttpClient 教程 (一) 前言 ... -
HTTP客户端服务
2012-03-20 15:39 13195.1 HttpClient门面 HttpClient接口代 ... -
Android 网络开发详解
2012-03-19 16:41 1178// 创建一个 HttpClient 实例 // 注意 H ... -
关于虚拟机AVD:Android Virtual Devices
2012-03-15 15:51 9371.拷贝虚拟SD卡文件至本地: DDMS视图->File ... -
向SD卡写文件
2012-03-15 15:47 962AndroidManifest.xml: SD卡创建与删除文 ... -
Android 近百个项目的源代码,覆盖Android开发的每个领域
2012-03-08 12:18 832Android PDF 阅读器 http://sourcefo ... -
关于谷歌地图的问题:requires unavailable shared library com.google.android.maps
2012-03-08 09:28 6414关于谷歌地图和百度地图的抉择: 补充:http://news ... -
Android Google Maps API key 申请
2012-03-07 15:17 19591.找debug.keystore文件路径: Eclipse- ... -
Android的断点设置
2012-03-07 14:46 3845Note: 在onCreate方法中加入Debug.waitF ...
相关推荐
Android 焦点事件
Android焦点控制原理及源码,求1积分
主要介绍了Android获取实时连接热点的设备IP 的相关资料,文中给大家补充介绍了安卓获取接入的Wifi热点设备的Ip地址的代码,需要的朋友可以参考下
最近开始接触Android TV端开发,有好多不适应,尤其是对焦点的控制,这也是手机app和电视app最大的不同之处。RecyclerView是个强大的控件,能代替ListView,GridView,能实现瀑布流,还能实现横向ListView,只需要一...
Android 开机默认是不会打开wifi热点的,即使上次手动打开了wifi热点,改修改可以保存上次打开热点的状态,实现开机打开wifi热点功能
android:layout_height="wrap_content" android:layout_width="fill_parent" android:orientation="vertical"> android:id="@+id/gallery" android:layout_width="fill_parent" android:layout_height=...
在android tv开发中最方便快捷的开发库,一两行代码搞定获取得焦点效果,列表移动框边缘拦截,事件处理
模拟android系统中控件之间焦点移动效果
android自带的输入法,在软键盘上实现焦点移动,支持上下左右按键,并支持回车输入,文档以LatinIME为例
android tv开发和移动端开发最大的不同就是多了一个焦点处理的逻辑。尤其是类似Recyclerview这样本身带有滑动效果,为了醒目的显示当前焦点在什么位置,需要滑动的时候回添加大量的动画、高亮、阴影等效果。 ...
android左右滚动焦点图 android:id="@+id/gallery" android:layout_width="fill_parent" android:layout_height="230px" android:spacing="10px" />
设置手机WiFi便携热点,并且监听热点打开与关闭,详情请参见我的博客http://blog.csdn.net/u011520181/article/details/46496377
android 指定wifi热点自动连接
AndroidTV中自定义RecyclerView 让当前焦点item显示在中间,调用smoothToCenter(pos)就可以。
android中焦点事件源码,项目中经常会用到的。值得收藏下。资源共享!
Android 一键建立热点,并生成用户名和密码
Android 蓝牙 音频焦点(Audio Focus)——卡音,多年安卓开发经验,从实际项目中获取到的经验,对安卓开发者非常有帮助。
Android中RecyclerView在TV中处理控件焦点移动,EditText值的修改,CheckBox复用等问题解决,详细了解请移步:http://blog.csdn.net/zxc514257857/article/details/74990099
基于Android的焦点新闻APP的设计与实现(源码 + 说明文档 + 演示视频) 第4章 系统总体设计 17 4.1 概述 17 4.2 设计原则 17 4.3 Android应用程序结构剖析 17 4.4 系统功能结构图 23 第5章 系统的实现 25 5.1 软件...
Android 开发wifi热点操作(开启和关闭,设置名称和密码)