android tv列表焦点记忆实现

作者: AndroidXing | 来源:发表于2018-04-01 18:38 被阅读359次

在Android tv中的开发中,经常要跟焦点打交道,一个常见的需求是要有焦点记忆功能,焦点移动到列表中的某一项中,焦点移出去,在回来时焦点还要定位到原来的项目上,对于这种需求,常见的实现方式是列表用用listview或者recyclerview实现,维护一个变量去存储上次的焦点位置,并在焦点变动或者按键事件中去维护这个变量和使用这个变量来定位.
具体实现
比如说用recyclerview实现列表时,在每个itemview的按键事件中,根据按键的方向和当前view的位置,判断是否是向外移走焦点的,如果是,那么就去设置父view也就是recyclerview的焦点模式,并且要保存当前view的位置信息

recyclerview.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);

在用户操作移回焦点时,由于前一步设置了焦点模式为block,因此会父view会首先获取焦点,增加焦点变动的事件处理:

recyclerview.setOnFocusChangeListener(new OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if(hasFocus){
                    Recyclerview recyclerview = (Recyclerview)v;
                    recyclerView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
                    if(mCurrentFocusPosition>0){
                        LayoutManager layoutManager = recyclerView.getLayoutManager();
                        View viewByPosition = layoutManager.findViewByPosition(mCurrentFocusPosition);
                        if(viewByPosition!=null){
                            viewByPosition.requestFocus();
                        }
                    }
                }
            }
        });

如代码所示,在焦点变动处理中,设置view的焦点模式,可以让子view获取焦点;拿到上一步保存的位置信息来手动设置焦点.
后面介绍另一种更简便的方法,有更好的封装性,不需要外层逻辑做维护处理.
文章已经发布,请查看:RecyclerView的焦点记忆封装

相关文章

网友评论

  • 不弃先森丶:你好 ,请问下mCurrentFocusPosition 需要怎么定义,是需要获取当前移动item的位置保存的吗?有完整点的demo吗,谢谢了
    AndroidXing:你好,mCurrentFocusPosition这个变量是用来记录上次焦点的位置.比如说一个常见的场景:tv上一个横向排列两行的recyclerview,在itemview中按键事件处理中,判断如果是在偶数位置号上并且是向上按键的,或者位置号为奇数并且是向下按键, 这些情况下那么可以认为焦点会移出去,记录下当前位置号给mCurrentFocusPosition.

本文标题:android tv列表焦点记忆实现

本文链接:https://www.haomeiwen.com/subject/vajacftx.html