Android RecyclerView 的平滑滚动不适用于初始滚动

Sam*_*ris 2 android android-scroll android-recyclerview linearlayoutmanager

我正在开发一款仅在一台运行 KitKat 的设备上运行的 Android 应用程序。

我使用的 RecylerView 的平滑滚动功能在其他物理平板电脑上运行,但 genymotion 不幸的是在它需要运行的一台设备上停止运行。

它不是滚动到某个位置,而是越过目标位置并一直滚动到底部,看起来非常糟糕。

我能够追踪 RecyclerView 类中抽象 SmoothScroller 的错误。

           if (getChildPosition(mTargetView) == mTargetPosition) {
                onTargetFound(mTargetView, recyclerView.mState, mRecyclingAction);
                mRecyclingAction.runIfNecessary(recyclerView);
                stop();
            } else {
                Log.e(TAG, "Passed over target position while smooth scrolling.");
                mTargetView = null;
            }
Run Code Online (Sandbox Code Playgroud)

我使用的是我在网上找到的 SnappingLinearLayoutManager,但将其换成了 Android 中的普通 LinearLayoutManager,但仍然遇到同样的问题。

该列表有 7 个项目长(用户一次可以看到 4 个项目),我滚动到第 5 个项目(位置 4)。

当我滚动到第三个时,我没有收到此错误。

此外,在我上下滚动列表一次后,错误就停止发生。

编辑: 我可以使用layoutManager.scrollToPositionWithOffset(); 但我正在尝试用平滑的滚动动画来做到这一点。

这是我的一些代码和详细信息:

private void setupMainRecyclerViewWithAdapter() {
    mainLayoutManager = new SnappingLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
    mainListRecyclerView.setLayoutManager(mainLayoutManager);

    settingsMainListAdapter = new SettingsListAdapter(SettingsActivity.this,
            settingsPresenter.getSettingsItems(),
            settingsPresenter);

    mainListRecyclerView.setAdapter(settingsMainListAdapter);

    mainListRecyclerView.addItemDecoration(new BottomOffsetDecoration(EXTRA_VERTICAL_SCROLLING_SPACE));
}

@Override
public void scrollMainList(boolean listAtTop) {
    if(listAtTop) {
        mainListRecyclerView.smoothScrollToPosition(4);
        moveMainMoreButtonAboveList();
    } else {
        mainListRecyclerView.smoothScrollToPosition(0);
        moveMainMoreButtonBelowList();
    }
}
Run Code Online (Sandbox Code Playgroud)

Gk *_*mon 8

如果您的调用recyclerView.smoothScrollToPosition(pos)将立即被调用,UI thread并且如果recyclerView'sAdapter太忙而无法生成视图项,则 ' 的调用smoothScrollToPosition将被错过,因为recyclerView没有数据可以平滑滚动。因此最好在后台线程中执行此操作recyclerView.post()。通过调用它,它会进入Main thread队列并在其他挂起的任务完成后执行。

因此,你应该做这样的事情,这对我的情况有用:

recyclerView.post(new Runnable() {
    @Override
    public void run() {
        recyclerView.smoothScrollToPosition(pos);
    }
});
Run Code Online (Sandbox Code Playgroud)