【问题标题】:Smooth Scroll Not Working on Initial Scroll for Android RecyclerView平滑滚动不适用于 Android RecyclerView 的初始滚动
【发布时间】:2017-04-23 05:53:42
【问题描述】:

我正在开发一款 Android 应用,该应用只能在一台运行 KitKat 的设备上运行。

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

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

我能够追踪到 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;
            }

我使用的是我在网上找到的 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();
    }
}

【问题讨论】:

  • 尝试改用layoutManager.scrollToPosition(index);
  • 对不起,我可以使用 layoutManager.scrollToPositionWithOffset();但我试图用平滑的滚动动画来做到这一点。很好的捕捉@BNK。我会将该编辑添加到我的问题中。
  • 是的,我尝试实施 mcochin 博客文章中的解决方案,但遇到了相同的“平滑滚动时越过了目标位置”。错误。我会调查另一个。感谢您的帮助!

标签: android android-recyclerview android-scroll linearlayoutmanager


【解决方案1】:

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

因此,您应该做一些适合我的情况的事情:

recyclerView.post(new Runnable() {
    @Override
    public void run() {
        recyclerView.smoothScrollToPosition(pos);
    }
});

【讨论】:

    【解决方案2】:

    好吧,我意识到为时已晚,但我尝试了一些不同的解决方案并找到了一个......

    在自定义 LinearSmoothScroller 中,我覆盖 updateActionForInterimTarget

    @Override protected void updateActionForInterimTarget(Action action) { action.jumpTo(position); }

    与scrollToPositionWithOffset相比,它看起来不是很流畅,但不是即时的。

    【讨论】:

      【解决方案3】:

      只需添加一行即可平滑滚动

      recyclerView.setNestedScrollingEnabled(false);
      

      它会正常工作

      【讨论】:

      • 为我工作,但谁能解释为什么会这样?
      • 这仅适用于带有嵌套滚动区域的回收站视图
      【解决方案4】:

      看看hasPendingAdapterUpdates()。您可以将其与协程的 delay() 或 Thread.sleep() 一起使用,以使支持数据在滚动之前可用。

      【讨论】:

        猜你喜欢
        • 2017-01-16
        • 1970-01-01
        • 2019-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多