Android 具有 gridlayout smoothScrollTo() 速度的 RecyclerView

Android RecyclerView with gridlayout smoothScrollTo() speed

我有一个带有 gridlayoutmanager 的 recyclerview。

如果我运行代码

recycler.smoothScrollTo(adapter.getItemCount())

回收器滚动到最后一个元素的速度非常快。我在 Whosebug 上尝试了一些解决方案来使滚动变慢,但都适用于 Linearlayoutmanager 而不是 Gridlayoutmanager。

有什么帮助吗?

我不能确定你的问题是什么。但我很幸运有一个非常简单的 GridLayoutManager recyclerview 演示,非常小的示例项目。我创建了一个 so 分支并添加了一个与您相同的按钮。

查找:https://github.com/Gryzor/GridToShowAds/compare/so?expand=1

.setOnClickListener { mainRecyclerView.smoothScrollToPosition(data.size) }

仅此一项就可以了。

查看源代码,这是一个非常简单的示例,用于不相关的东西,但恰好有一辆带网格布局的房车:)

更新

您真正想要的是控制 recyclerView 滚动的速度。好的

  1. 驱动滚动的不是 RecyclerView,实际上是 LayoutManager。怎么会?

如果您查看 RV 的源代码...

public void smoothScrollToPosition(int position) {

    ...

    mLayout.smoothScrollToPosition(this, mState, position);
}

所以它最终调用 mLayout。这是什么?

@VisibleForTesting LayoutManager mLayout;

因此,您的 LayoutManager#smoothScroll... 方法已被使用。

现在为科学反编译GridLayoutManager:

@Override
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
        int position) {
    LinearSmoothScroller linearSmoothScroller =
            new LinearSmoothScroller(recyclerView.getContext());
    linearSmoothScroller.setTargetPosition(position);
    startSmoothScroll(linearSmoothScroller);
}

注意:这个方法实际上在LinearLayoutManager中,因为GridLayoutManager是一个子class,它不会覆盖方法

一个LinearSmoothScroller!;虽然没有指定速度的参数...

看看:

public class LinearSmoothScroller extends RecyclerView.SmoothScroller {

    private static final boolean DEBUG = false;
    private static final float MILLISECONDS_PER_INCH = 25f;
    private static final int TARGET_SEEK_SCROLL_DISTANCE_PX = 10000;
...

}

此 class 有一个 start() 方法,描述为: * Starts a smooth scroll for the given target position.

谁叫这个?

mLayout.smoothScrollToPosition 方法在 startSmoothScroll(...) 调用结束时执行。

public void startSmoothScroll(SmoothScroller smoothScroller) {

Starts a smooth scroll using the provided {@link SmoothScroller}.

mSmoothScroller.start(mRecyclerView, this);

所以...代替所有这些,您的问题的答案是:

您需要通过子class创建 GridLayoutManager 的扩展,并在其中覆盖 smoothScrollToPosition 方法,以提供您自己的 Scroller 逻辑。

虽然线程要仔细,LayoutManager 并不是有史以来的 "simplest" classes,掌握它们可能相当复杂。

祝你好运! :)

我的简单工作解决方案目前仍在实施计时器,然后使用它。

        final CountDownTimer scrollUp_timer = new CountDownTimer(50000, 30) {
        @Override
        public void onTick(long millisUntilFinished) {
            if (layoutManager != null && layoutManager.findFirstVisibleItemPosition() != 0) searchRecyclerView.smoothScrollToPosition(layoutManager.findFirstVisibleItemPosition()-1);
        }

            @Override
            public void onFinish() {
                try{
                }catch(Exception e){
                // log
                }
            }
        };

        scrollUp.setOnDragListener(new View.OnDragListener() {
            @Override
            public boolean onDrag(View view, DragEvent dragEvent) {
            layoutManager = ((GridLayoutManager)searchRecyclerView.getLayoutManager());
            int action = dragEvent.getAction();
            if (action == DragEvent.ACTION_DRAG_ENTERED) {
                scrollUp_timer.start();

            } else if (action == DragEvent.ACTION_DRAG_EXITED) {
                searchRecyclerView.scrollBy(0,0);
                scrollUp_timer.cancel();
            }
            return true;
        }
    });