2

我正在开发一款 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();
    }
}
4

4 回答 4

6

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

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

recyclerView.post(new Runnable() {
    @Override
    public void run() {
        recyclerView.smoothScrollToPosition(pos);
    }
});
于 2020-04-24T07:48:48.357 回答
3

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

在自定义 LinearSmoothScroller 我覆盖 updateActionForInterimTarget

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

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

于 2017-07-04T08:59:42.033 回答
2

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

recyclerView.setNestedScrollingEnabled(false);

它会正常工作

于 2017-08-31T15:19:05.807 回答
0

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

于 2021-10-31T18:11:05.210 回答