今天解决了一个Android平台下的焦点问题。发现其中关键问题的所在是Android的touchMode。从JavaSwing平台过来的人,都会关注setFocusable()和requestFocus()方法,但是在Android的View中还有另外的两个个方法,setFocusableInTouchMode()和requestFocusFromTouch()方法。这个两个方法就是解决Android上的焦点获取问题的关键。

同时在View类中,还有一个isInTouchMode(),可以帮助我们在监听Focuse事件时判断是否执行click(). 代码如下:

复制到剪贴板  XML/HTML代码
  1. ImageButton.OnFocusChangeListener mFocusChangeListener = new ImageButton.OnFocusChangeListener(){
  2. public void onFocusChange(View v, boolean hasFocus) {
  3. Log.d("FocuseChange", "Focuse has changed.");
  4. if (hasFocus) {
  5. // 如果是touchmode就执行click,否则就会只是选中。
  6. v.setBackgroundDrawable(getResources().getDrawable(R.drawable.));
  7. if (v.isInTouchMode()){
  8. ((ImageButton)v).performClick();
  9. }
  10. } else {
  11. v.setBackgroundDrawable(getResources().getDrawable(R.));
  12. v.getBackground().setAlpha(100);
  13. }
  14. }
  15. };

系统框架将处理日常的焦点移动来响应用户的输入,它包刮改变焦点(当界面是被移除,隐藏,或者作为一个新的View变为可用状态),通过isFocusable()这个方法我们可以知道view是否具有接受焦点的资格,也可以通过setFocusable().来设置view接受焦点的资格,对应在触摸模式下,你可以调用isFocusableInTouchMode().来获知是否有焦点来响应点触,也可以通过setFocusableInTouchMode().来设置是否有焦点来响应点触的资格.
系统框架控制焦点移动到另一个组件的算法是在某一方向上邻近的组件,在极个别情况下,默认的算法可能不符合开发者的预想要求,在这种情况下,你可以覆写下列XML属性的布局文件:nextFocusDown ,nextFocusLeftnextFocusRight ,和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键时,哪个控件将获得焦点

下面是其代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent">
  6. <Button
  7. style="@style/clockFaceNum"
  8. android:text="12"
  9. android:id="@+id/button12"
  10. android:layout_alignParentTop="true"
  11. android:layout_centerHorizontal="true"
  12. android:nextFocusUp="@+id/button11"
  13. android:nextFocusLeft="@+id/button11"
  14. android:nextFocusRight="@+id/button1"
  15. android:nextFocusDown="@+id/button1">
  16. </Button>
  17. <Button
  18. style="@style/clockFaceNum"
  19. android:text="11"
  20. android:id="@+id/button11"
  21. android:layout_below="@+id/button12"
  22. android:layout_toLeftOf="@+id/button12"
  23. android:nextFocusUp="@+id/button10"
  24. android:nextFocusLeft="@+id/button10"
  25. android:nextFocusRight="@+id/button12"
  26. android:nextFocusDown="@+id/button12">
  27. </Button>
  28. <Button
  29. style="@style/clockFaceNum"
  30. android:text="1"
  31. android:id="@+id/button1"
  32. android:layout_below="@+id/button12"
  33. android:layout_toRightOf="@+id/button12"
  34. android:nextFocusUp="@+id/button12"
  35. android:nextFocusLeft="@+id/button12"
  36. android:nextFocusRight="@+id/button2"
  37. android:nextFocusDown="@+id/button2">
  38. </Button>
  39. <Button
  40. style="@style/clockFaceNum"
  41. android:text="10"
  42. android:id="@+id/button10"
  43. android:layout_below="@+id/button11"
  44. android:layout_toLeftOf="@+id/button11"
  45. android:nextFocusUp="@+id/button9"
  46. android:nextFocusLeft="@+id/button9"
  47. android:nextFocusRight="@+id/button11"
  48. android:nextFocusDown="@+id/button11">
  49. </Button>
  50. <Button
  51. style="@style/clockFaceNum"
  52. android:text="2"
  53. android:id="@+id/button2"
  54. android:layout_below="@+id/button1"
  55. android:layout_toRightOf="@+id/button1"
  56. android:nextFocusUp="@+id/button1"
  57. android:nextFocusLeft="@+id/button1"
  58. android:nextFocusRight="@+id/button3"
  59. android:nextFocusDown="@+id/button3">
  60. </Button>
  61. <Button
  62. style="@style/clockFaceNum"
  63. android:text="9"
  64. android:id="@+id/button9"
  65. android:layout_below="@+id/button10"
  66. android:layout_toLeftOf="@+id/button10"
  67. android:nextFocusUp="@+id/button8"
  68. android:nextFocusLeft="@+id/button8"
  69. android:nextFocusRight="@+id/button10"
  70. android:nextFocusDown="@+id/button10">
  71. </Button>
  72. <Button
  73. style="@style/clockFaceNum"
  74. android:text="3"
  75. android:id="@+id/button3"
  76. android:layout_below="@+id/button2"
  77. android:layout_toRightOf="@+id/button2"
  78. android:nextFocusUp="@+id/button2"
  79. android:nextFocusLeft="@+id/button2"
  80. android:nextFocusRight="@+id/button4"
  81. android:nextFocusDown="@+id/button4">
  82. </Button>
  83. <Button
  84. style="@style/clockFaceNum"
  85. android:text="8"
  86. android:id="@+id/button8"
  87. android:layout_below="@+id/button9"
  88. android:layout_toRightOf="@+id/button9"
  89. android:nextFocusUp="@+id/button7"
  90. android:nextFocusLeft="@+id/button7"
  91. android:nextFocusRight="@+id/button9"
  92. android:nextFocusDown="@+id/button9">
  93. </Button>
  94. <Button
  95. style="@style/clockFaceNum"
  96. android:text="4"
  97. android:id="@+id/button4"
  98. android:layout_below="@+id/button3"
  99. android:layout_toLeftOf="@+id/button3"
  100. android:nextFocusUp="@+id/button3"
  101. android:nextFocusLeft="@+id/button3"
  102. android:nextFocusRight="@+id/button5"
  103. android:nextFocusDown="@+id/button5">
  104. </Button>
  105. <Button
  106. style="@style/clockFaceNum"
  107. android:text="7"
  108. android:id="@+id/button7"
  109. android:layout_below="@+id/button8"
  110. android:layout_toRightOf="@+id/button8"
  111. android:nextFocusUp="@+id/button6"
  112. android:nextFocusLeft="@+id/button6"
  113. android:nextFocusRight="@+id/button8"
  114. android:nextFocusDown="@+id/button8">
  115. </Button>
  116. <Button
  117. style="@style/clockFaceNum"
  118. android:text="5"
  119. android:id="@+id/button5"
  120. android:layout_below="@+id/button4"
  121. android:layout_toLeftOf="@+id/button4"
  122. android:nextFocusUp="@+id/button4"
  123. android:nextFocusLeft="@+id/button4"
  124. android:nextFocusRight="@+id/button6"
  125. android:nextFocusDown="@+id/button6">
  126. </Button>
  127. <Button
  128. style="@style/clockFaceNum"
  129. android:text="6"
  130. android:id="@+id/button6"
  131. android:layout_below="@+id/button5"
  132. android:layout_centerHorizontal="true"
  133. android:nextFocusUp="@+id/button5"
  134. android:nextFocusLeft="@+id/button5"
  135. android:nextFocusRight="@+id/button7"
  136. android:nextFocusDown="@+id/button7">
  137. </Button>
  138. </RelativeLayout>

下图中是假定在键12开始按down键时的焦点切换顺序:

步骤4 设置界面的初始控件焦点

在每个页面加载时,可以设置界面中初始的控件焦点,以方便用户的定位操作,只需要在控件中加入即可。比如:

  1. <Button
  2. style="@style/clockFaceNum"
  3. android:text="12"
  4. android:id="@+id/button12"
  5. android:layout_alignParentTop="true"
  6. android:layout_centerHorizontal="true"
  7. android:nextFocusUp="@+id/button11"
  8. android:nextFocusLeft="@+id/button11"
  9. android:nextFocusRight="@+id/button1"
  10. android:nextFocusDown="@+id/button1">
  11. <requestFocus />
  12. </Button>

小结

作为开发者,一定要记住由于Android设备的多样性,用户如何在界面上方便地进行输入或在不同的控件中来回切换是十分重要的,本文简单介绍了用户如何自定义控件的焦点切换顺序,这对于用户界面的体验是很有好处的。

项目实践:

界面中有多个view的时候,按上下左右键 经常找不到 焦点在哪里,解决方法是把所有的view 先 setFocus(false), 然后再把想获取焦点的view.setFocus(ture)

再 view.requestFocus();

android 焦点问题的更多相关文章

  1. android的EditText重新获取焦点问题

    在android开发过程中关于EditText在setFocusable(false);后,当需要再次获得焦点输入时设置setFocusable(true);后还是无法获得焦点的问题: 解决办法: 对 ...

  2. android去掉EditView的默认焦点问题

    在EditText的父级控件中找一个,设置成 <LinearLayout android:layout_width="0dp" android:layout_height=& ...

  3. Android EditText不弹出输入法焦点问题的总结

    转自:http://mobile.51cto.com/aprogram-403138.htm 看一个manifest中Activity的配置,如果这个页面有EditText,并且我们想要进入这个页面的 ...

  4. 【转】android去掉EditView的默认焦点问题

    原文网址:http://www.111cn.net/sj/android/54680.htm 做一个输入框时发现android中EditView的默认焦点了,这种问题如果是在输入框还好,但在搜索页面或 ...

  5. Android中EditText焦点问题

    https://www.jianshu.com/p/3d31d681f4bc 问题:当EditText失去焦点时做内容校验 场景:用户编辑EditText将内容清空,当点击空白地方时关闭软键盘,同时校 ...

  6. android 所有焦点问题

    一. 主动获取焦点 setFocusable(true);    //  是设置能否获得焦点而已.. requestFocus();          //是让控件得到焦点 requestFocusI ...

  7. android:listView Button 焦点问题

    要想listView的item与其上的button皆能得到焦点响应: 在listView item 的布局中: 在<RelativeLayout>中 android:descendantF ...

  8. Android中涉及到的焦点问题,focusable,clickable,enabled

    先摘抄下stackoverflow上一个启示了我的回答: try by Changing your code as: private OnClickListener saveButtonListene ...

  9. Android BaseAdapter和ViewHolder 优化 解决ListView的item抢焦点问题和item错乱问题

    首先赞下hyman大神 曾经仅仅是简单的重写个BaseAdapter,将getView方法保持抽象.而ViewHolder没有抽象过. .. ViewHolder (用了一个集合+泛型管理存取view ...

随机推荐

  1. android 5.0 -- Activity 过渡动画

    android 5.0 提供3种过渡动画: 进入 退出 进入退出包括如下效果: explode 分解:屏幕中间进出 slide 滑动:屏幕边缘进出 fade 淡出:改变透明度来添加或者移除视图 共享 ...

  2. ios根据文本自适应 然后 搭建类似如下效果

    UIView * headView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.tbSecond.size.width, 0)]; hea ...

  3. JS复习:第八章

    一.全局作用域: 所有在全局作用域中声明的变量.函数都会变成window对象的属性和方法.全局变量不能通过delete操作符删除,而window对象上定义的属性可以. 二.窗口大小 使用resizeT ...

  4. 【Sort】插入排序

    今晚更新几个排序算法 插入排序,时间复杂度O(n^2),从前往后遍历,每遍历到一个值的时候,其前面的所有值已经完成排序,把这个值插入适当位置 void intersort(int *nums,int ...

  5. hdu_5884_Sort(二分+单调队列)

    题目链接:hdu_5884_Sort 题意: 有n个数,每个数有个值,现在你可以选择每次K个数合并,合并的消耗为这K个数的权值和,问在合并为只有1个数的时候,总消耗不超过T的情况下,最小的K是多少 题 ...

  6. hdu2141AC代码分享

    #include <iostream> #include <algorithm> using namespace std; const int N = 505; /////// ...

  7. 5、Web应用程序中的安全向量 -- Open Redirect Attack(开放重定向)

    开放重定向攻击的概念:那些通过请求(如查询字符串和表单数据)指定重定向URL的Web应用程序可能会被篡改,而把用户重定向到外部的恶意URL. 在执行重定向之前需先检查目标地址的有效性,可使用Url.I ...

  8. ubuntu 调试库

    .安装带有调试信息的libc: sudo apt-get install libc6-dbg .下载libc源码 a.选定一个放置源码的目录并进入,如 /home/kent/dev-os/libc6- ...

  9. nefu 1191 平行宇宙 (bfs)

    Description 小k是时空贸易者,他经常在两个平行宇宙之间往来经商,现在他要从S点到达E点,问最少需要多长时间.(已知小k在同一个宇宙中只能向上下左右四个方向移动,每次移动需要1个单位时间,且 ...

  10. sql标识符和格式

    数据库名是一个标识符,表名也是一个标识符,在SQL SERVER中标识符分为两类: (1).常规标识符;(2).分隔标识符两者重要的区别:常规标识符必须严格遵守命名的规定,而分隔标识符则可以不遵守命名 ...