在 RecyclerView 中快速滚动 [英] Snappy scrolling in RecyclerView

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

问题描述

我正在尝试将新的 RecyclerView 类用于我希望组件在滚动时捕捉到特定元素的场景(想到旧的 Android Gallery作为具有中心锁定项目的此类列表的示例).

I am trying to use the new RecyclerView class for a scenario where I want the component to snap to a specific element when scrolling (The old Android Gallery comes to mind as an example of such a list with a center-locked item).

这是我目前采用的方法:

This is the approach that I am taking thus far:

我有一个接口,ISnappyLayoutManager,它包含一个方法,getPositionForVelocity,它计算视图应该在给定初始滑动速度的哪个位置结束滚动.>

I have an interface, ISnappyLayoutManager, which contains a method, getPositionForVelocity, which calculates at which position the view should end the scrolling given the initial fling velocity.

public interface ISnappyLayoutManager {
    int getPositionForVelocity(int velocityX, int velocityY);  
}

然后我有一个类,SnappyRecyclerView,它子类化 RecyclerView 并覆盖它的 fling() 方法,以便将视图抛出正确的数量:

Then I have a class, SnappyRecyclerView, which subclasses RecyclerView and overrides its fling() method in such a manner as to fling the view the exact right amount:

public final class SnappyRecyclerView extends RecyclerView {

    /** other methods deleted **/

    @Override
    public boolean fling(int velocityX, int velocityY) {
        LayoutManager lm = getLayoutManager();

        if (lm instanceof ISnappyLayoutManager) {
            super.smoothScrollToPosition(((ISnappyLayoutManager) getLayoutManager())
                    .getPositionForVelocity(velocityX, velocityY));
        }
        return true;
    }
}

出于多种原因,我对这种方法不太满意.首先,必须将其子类化以实现某种类型的滚动似乎与RecyclerView"的哲学背道而驰.其次,如果我只想使用默认的 LinearLayoutManager,这会变得有些复杂,因为我必须弄乱它的内部结构以了解它的当前滚动状态并准确计算它滚动到的位置.最后,这甚至没有考虑到所有可能的滚动场景,就像您移动列表然后暂停然后抬起手指一样,没有发生 fling 事件(速度太低),因此列表保持在一半位置.这可能可以通过向 RecyclerView 添加滚动状态侦听器来解决,但这也感觉很麻烦.

I am not very happy with this approach for several reasons. First of all, it seems counter to the philosophy of the 'RecyclerView' to have to subclass it to implement a certain type of scrolling. Second, if I want to just use the default LinearLayoutManager, this becomes somewhat complex as I have to mess around with its internals in order to understand its current scroll state and calculate out exactly where this scrolls to. Finally, this doesn't even take care of all the possible scroll scenarios, as if you move the list and then pause and then lift a finger, no fling event occurs (the velocity is too low) and so the list remains in a halfway position. This can possibly be taken care of by adding an on scroll state listener to the RecyclerView, but that also feels very hacky.

我觉得我一定错过了什么.有没有更好的方法来做到这一点?

I feel like I must be missing something. Is there a better way to do this?

推荐答案

With LinearSnapHelper,现在这很容易.

With LinearSnapHelper, this is now very easy.

你需要做的就是:

SnapHelper helper = new LinearSnapHelper();
helper.attachToRecyclerView(recyclerView);

就是这么简单!请注意,从版本 24.2.0 开始,支持库中添加了 LinearSnapHelper.

It's that simple! Note that LinearSnapHelper was added in the Support Library starting from version 24.2.0.

这意味着您必须将此添加到您的应用模块的 build.gradle

Meaning you have to add this to your app module's build.gradle

compile "com.android.support:recyclerview-v7:24.2.0"

AndroidX LinearSnapHelper

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

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