RecyclerView,出现丢焦点问题

RecyclerView嵌套RecyclerView

或者嵌套了LinearLayout,带上属性android:focusable="true" android:focusableInTouchMode="true"

向上翻页,加载item时出现丢焦点。

原因是此时上面的item还没有加载出来。

解决办法:

自定义LinearLayoutManager重写onFocusSearchFailed()方法,返回要获取焦点的item。

 

@Override
public View onFocusSearchFailed(View focused, int focusDirection,
                                RecyclerView.Recycler recycler,
                                RecyclerView.State state) {
    // Need to be called in order to layout new row/column
    View nextFocus = super.onFocusSearchFailed(focused, focusDirection, recycler, state);

    if (nextFocus == null) {
        return null;
    }
    /**
     * 获取当前焦点的位置
     */
    int fromPos = getPosition(getFocusedChild());
    /**
     * 获取我们希望的下一个焦点的位置
     */
    int nextPos = getNextViewPos(fromPos, focusDirection);

    return findViewByPosition(nextPos);
}

private int getNextViewPos(int fromPos, int direction) {
        int offset = getOffset(direction);
        return hitBorder(fromPos, offset) ? fromPos : fromPos + offset;
    }

    private int getOffset(int direction) {
        int spanCount = getSpanCount();
        int orientation = getOrientation();

        if (orientation == VERTICAL) {
            switch (direction) {
                case View.FOCUS_DOWN:
                    return spanCount;
                case View.FOCUS_UP:
                    return -spanCount;
                case View.FOCUS_RIGHT:
                    return 1;
                case View.FOCUS_LEFT:
                    return -1;
            }
        } else if (orientation == HORIZONTAL) {
            switch (direction) {
                case View.FOCUS_DOWN:
                    return 1;
                case View.FOCUS_UP:
                    return -1;
                case View.FOCUS_RIGHT:
                    return spanCount;
                case View.FOCUS_LEFT:
                    return -spanCount;
            }
        }

        return 0;
    }

    private int getSpanCount() {
        return 1;
    }

    private boolean hitBorder(int from, int offset) {
        int spanCount = getSpanCount();

        if (Math.abs(offset) == 1) {
            int spanIndex = from % spanCount;
            int newSpanIndex = spanIndex + offset;
            return newSpanIndex < 0 || newSpanIndex >= spanCount;
        } else {
            int newPos = from + offset;
            return newPos < 0 && newPos >= spanCount;
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值