RecyclerView集中滚动 [英] RecyclerView focus scrolling

查看:1029
本文介绍了RecyclerView集中滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一般两列,最多八个RecyclerView。我们使用了大量的D-PAD导航。我们有滚动时出了问题,重点项目会跳到左到右。见照片:

I have a RecyclerView with usually two columns and up to eight. We use a lot of D-PAD navigation. We have a problem when scrolling, the focused item will jump from left to right. See photos:

我注意到,如果接下来即将到来的物品被缓存,还有滚动时没有关注的问题。我还有一个问题是,我的重点项目会出现下面我粘头。这是不希望的。所以,我觉得如果我做了这么滚动时,将有一种门槛。这样,当焦点被关闭屏幕一个项目内,将滚动。这种方式的重点是从未在最底层,或最顶部。

I noticed that if the items that are coming up next are cached, there is no focus problem when scrolling. Another problem I have is my focus item can appear below my sticky header. This is not desired. So I feel like if I made it so when scrolling it would have a sort of "threshold". This way when the focus is within one item of being off screen, it will scroll. This way the focus is never at the very bottom, or the very top.

考虑到这一点,我想这种做法没有运气:

With that in mind, I tried this approach with no luck:

RecyclerView rv;

@Override
public void onFocusChange(View v, boolean hasFocus) {
    if(!v.hasFocus()) {
        Log.w(TAG, "View v did not have focus");
        return;
    }

    final int index = rv.getChildPosition(v); //adapter pos
    if(index == NO_POSITION) {
        Log.w(TAG, "Recycler view did not have view");
        return;
    }

    int position = rv.indexOfChild(v);  // layout pos
    int lastPos = rv.getChildCount();   // layout pos
    int span = getLayoutManager().getSpanCount();
    int threshold = 2 * span;
    Log.d(TAG, String.format("Position: %1$d. lastPos: %2$d. span: %3$d. threshold: %4$d", position, lastPos, span, threshold));

    if (position >= (lastPos - threshold)) {
        //scroll down if possible
        int bottomIndex = rv.getChildPosition(rv.getChildAt(lastPos));
        if (bottomIndex < getItemCount()) {
            //scroll down
            int scrollBy = v.getHeight();
            recycler.scrollBy(0, scrollBy);
            Log.d(TAG, String.format("Scrolling down by %d", scrollBy));

        }

    } else if (position <= threshold) {
        //scroll up if possible
        int topIndex = rv.getChildPosition(rv.getChildAt(0));
        if (topIndex > 0) {
            //scroll up
            int scrollBy = v.getHeight();
            recycler.scrollBy(0, -scrollBy);
            Log.d(TAG, String.format("Scrolling up by %d", -scrollBy));
        }
    }
}

我愿意就如何滚动时管理的重点任何想法。

I am open to any ideas on how to manage the focus when scrolling.

推荐答案

我报这个错误给AOSP问题跟踪:的问题190526

I reported this bug to AOSP issue tracker: issue 190526

我可以从源代码看到的问题是,因为 GridLayoutManager 用途的实施 LinearLayoutManager onFocusSearchFailed()当焦点接近 RecyclerView 的内边框被调用。 LinearLayoutManager 的实施只是提供首/末(取决于滚动方向)元素。因此,焦点跳转到新行的第一个/最后一个元素。

As I can see from source the issue is because GridLayoutManager uses LinearLayoutManager's implementation of onFocusSearchFailed() which is called when focus approaches the inner border of RecyclerView. LinearLayoutManager's implementation just offers first/last (depends on scrolling direction) element. Hence focus jumps to first/last element of new row.

我的办法解决这个问题

这篇关于RecyclerView集中滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆