转载:http://phenom.iteye.com/blog/1905520

开发android机顶盒应用 事件,焦点处理

机顶盒应用不同于手机应用,因为多数是没有触摸屏的,只能靠遥控器,所以要保持一个焦点的位置,让用户知道当前操作作用的对象.
然而一些app,依据系统对focus的判断,会出现的状况:
上下导航时,不是想要的结果.
边缘移动时,会出现焦点丢失的状况.
有时想直接定位到某个位置上.

所有这些,都是针对机顶盒应用特有的,之前没有接触过,也搜索一些网上文章,坑人的居多,有用的没有.

现在说下本人的 实践情况:
setnextfocusid,还有类似的方法,是不可行的.因为它无法控制,而且是依赖系统定位.而且有时从一个控件到另一个控件,有时又到其它控件上,它无法做到.

于是就探索了keyevent.总结后,得出结论.需要覆盖Activity的public boolean dispatchKeyEvent(KeyEvent event) 方法.
然后可以依据些方法进行相应处理,可以解决绝大多数问题,(极少部分,我也无语.)

Java代码 收藏代码

 一个按键有两个触发点,一是up,一是down,如果需要指定焦点,使用view.requestFocus(),而且需要在down上执行,因为up时,系统已经定位新的焦点了.再执行就未必是想要的结果.      int keyCode=event.getKeyCode();      if (event.getAction()==KeyEvent.ACTION_UP) {      up事件,这里多数情况不需要处理.      } else {down事件      或许可以直接覆盖onKeyDown方法,而不是这个.      if(keyCode==KeyEvent.KEYCODE_DPAD_UP){       } else if (keyCode==KeyEvent.KEYCODE_DPAD_LEFT) {      } else if (keyCode==KeyEvent.KEYCODE_DPAD_RIGHT) {      } else if (keyCode==KeyEvent.KEYCODE_DPAD_DOWN) {      } else if (keyCode==KeyEvent.KEYCODE_DPAD_CENTER||keyCode==KeyEvent.KEYCODE_ENTER) {      }      这是主要处理的遥控器的几个方向,最后一个,有些机顶盒太恶劣了,你自己看着办吧.      方向不是研究重点.      这个程序涉及的内容较多,ui使用Fragment构造,所以还更恶心一些.      比如在一个Fragment中的焦点,先得到Fragment,Fragment top=getFragmentManager().findFragmentById(R.id.content);      然后如果需要直接定位到某一个焦点,需要调用top中的一些方法,比如可以类型转换为xxFragment,然后调用.但是针对每一个Fragment都这样处理上一个,下一个焦点,累死人了.而且系统会变慢.      多数情况需要依赖系统的定位,然后针对一些特殊的情况,系统定位失败的再进行定向处理.      出现问题的多数是GridView,这样的ViewGroup控件,比如现在有两行,焦点在第一行,然后向下按键KeyEvent.KEYCODE_DPAD_DOWN.在event.getAction()==KeyEvent.ACTION_DOWN中判断,会出现不想要的结果,比如它不会定位下一个焦点还是GridView,也不是它的下一行,因为它把整个GridView当成一个控件,下一个:final View downView=currentFocus.focusSearch(View.FOCUS_DOWN);搜索得到的downView有可能是空的,有可能是另一个控件,比如Button,然而在焦点出现异常时,不能在这里return true;这样是无法到它第二行的.在ACTION_UP中,如果之前的down不返回true,会得到下一行焦点.      这里提供另一种方法:还是在down中处理:      if (currentFocus instanceof GridView) {           GridView gridView=(GridView) currentFocus.getParent();           int column=gridView.getNumColumns();           int selPos=gridView.getSelectedItemPosition();           int count=gridView.getAdapter().getCount();           Log.d(TAG, "selPos:"+selPos+" count:"+count+" column:"+column);           if (selPos>=column*2) {   //如果是GridView的最下边,再向下,需要翻页.               if (fragment.pageDown()) {               Log.d(TAG, "向下翻页了.");               }               return true;           } else {               if (count<=column||(count>column&&count<=column*2&&selPos>=column)) {                   if (fragment.pageDown()) {                       Log.d(TAG, "品牌向下翻页了,已经是最后一页.");                         }                                              return true;                                          }                                      }      }      这样可以判断当GridView的焦点在第一行时,如果选中项的位置也是第一行,可以依据系统定位,它会移动到第二行,依次类推.如果是最后一行,其实也可以依据系统定位,如果没有特殊要求.      }      还有些针对GridView,比如移动边缘,左边缘,再向左,焦点保持不变的位置,就可以依据这个选中的位置与它的列数判断了,然后return true;消耗这次事件,就可以了.      其它单个控件,几乎都可以直接判断View right=currentFocus.focusSearch(View.FOCUS_RIGHT); 这四个方向的情况 就可以了.因为不存在控件内部的定位.  

如果各位大侠有更好的办法,请留言.

-------------------------------------------------  

- 你我都是程序猿,适当共享信息,提高能力,是一个it人应尽的责任. 两个程序猿,即使在一个公司,能成为竞争对手(正规的竞争)的可能性接近于零.
- 就像高中同学,考大学,成为竞争对手的概率是一样的,接近0,必须是:分数接近,考同一所学校,同一专业,而且还得都接近分数线,你上了他就不能上的这种.

-------------------------------------------------  

更多相关文章

  1. Android(安卓)UI基础——EditText控件
  2. android之论setContentView(R.layout.activity_main)位置的重要
  3. android 动态修改 TextView的width属性
  4. Android(安卓)studio APP开发 ListView控件的建立和使用
  5. Android自定义进度条——圆角横向进度条
  6. android webview图片文件上传兼容性问题——上传控件点击无效的
  7. Android入门之Style与Theme用法实例解析
  8. Android中如何让图片自适应控件的大小
  9. Android中动态改变控件的大小的一种方法

随机推荐

  1. Android读取assets目录下文件数据内容
  2. Android(安卓)创建与解析XML(一)—— 概述
  3. android 轻松实现语音识别
  4. Android中资源文件的使用
  5. Android(安卓)Webview 基本使用总结
  6. 使用jQuery Mobile和Phone Gap开发Androi
  7. Qt on Android:让 Qt Widgets 和 Qt Quick
  8. Android的Activity屏幕切换动画(二)-左右
  9. Google Android(安卓)SDK开发范例大全(第
  10. Android活动Acitivity启动模式之singleTo