设为首页收藏本站

数字电视开发论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

快捷登录

胜天工科技销售各种数字电视信号调制卡胜天工科技销售各种数字电视信号码流卡

【游客、新手、注册会员的区别】 【积分策略和会员晋级说明】 【发帖和附件上传规则】 【如何下载感兴趣的资料】 【如何获取梦游币】 【侵权资料处理及免责说明】
查看: 6876|回复: 0

开发android机顶盒应用中的事件和焦点处理

[复制链接]
  • TA的每日心情
    开心
    3 天前
  • 签到天数: 2059 天

    [LV.Master]伴坛终老

    新浪微博达人勋

    发表于 2014-6-6 15:43:21 | 显示全部楼层 |阅读模式
    分享到:
    消息来自- 北京朝阳
    机顶盒应用不同于手机应用,因为多数是没有触摸屏的,只能靠遥控器,所以要保持一个焦点的位置,让用户知道当前操作作用的对象。
    然而一些app,依据系统对focus的判断,会出现的状况:
    上下导航时,不是想要的结果。
    边缘移动时,会出现焦点丢失的状况。
    有时想直接定位到某个位置上。

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

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

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

    一个按键有两个触发点,一是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); 这四个方向的情况就可以了,因为不存在控件内部的定位。
      
    如果各位大侠有更好的办法,请留言。
    踩过的脚印
    您需要登录后才可以回帖 登录 | 注册 新浪微博登陆

    本版积分规则

    嗨!您好:
    欢迎来到数字电视开发论坛。
    我的名字叫梦梦
    很高兴能够为您服务!
    如果已经注册【立即登录】
    还没有账号请【注册】
    嗨!您好:
    欢迎来到数字电视开发论坛。
    我的名字叫梦梦
    很高兴能够为您服务!
    如果已经注册【立即登录】
    还没有账号请

    QQ|小黑屋|手机版|Archiver|数字电视开发网 ( 京ICP备16008897号-5   

    GMT+8, 2018-4-24 12:35 , Processed in 0.244519 second(s), 38 queries , Gzip On.

    Powered by Discuz! X3.1

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表