RecyclerView 上 LinearLayoutManager 的 scrollToPositionWithOffset 不起作用

scrollToPositionWithOffset from LinearLayoutManager on RecyclerView not working

我正在尝试用 RecyclerView 制作一个水平的粘性图像列表,我想用 scrollToPositionWithOffset 将它们移动像素偏移量。我认为将 0 作为 position 传递,将我想向右/向左移动的像素作为 offset

但它不起作用,列表保持不变,未滚动,它不会移动。这是我的实现:

final LargeImageAdapter mLargeImageAdapter = new LargeImageAdapter(this);
linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(mLargeImageAdapter);

seekBar = (SeekBar)findViewById(R.id.seekBar);
seekBar.setMax(7000);
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        int scrollToDX = progress;

        ((LinearLayoutManager)recyclerView.getLayoutManager()).scrollToPositionWithOffset(0, scrollToDX);
        // tried invoking also linearLayoutManager instead getLayoutManager.
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
});

我做错了什么?

非常感谢。

此致。

拉斐尔.

我终于用上了:

recyclerView.scrollBy(int offsetX, int offsetY); 设置 offsetY = 0 现在可以使用了。

我不明白这个函数有什么用scrollToPositionWithOffset

第一个问题的迟到答案,以及对答案的补充:

您的方法更适合您的个人需求,因为 scrollToPositionWithOffset 并非旨在满足您的需求。

作为 doc says here:

[...]Resolved layout start depends on [...] getLayoutDirection(android.view.View) [...]

这意味着它会在布局方向上偏移滚动目标位置,在您的情况下是垂直的。

I don't understand what's the utility of the function scrollToPositionWithOffset.

它不仅允许滚动到列表中的给定项目,还可以将其定位在更“可见”或其他方便的地方。

我遇到了类似的问题。我的问题是我的 recyclerview 与其父布局的大小不同。我通过将回收站视图宽度和高度设置为 match_parent 解决了这个问题。我不知道为什么会出现这种情况。

最近我也遇到了这个问题,我在onScrolled()时直接调用scrollToPositionWithOffset,但没有任何变化,我转向scrollToPosition()甚至scrollBy()但是没用,最后我尝试延迟它所以它起作用,第一次我延迟 50ms,但两周后我发现这还不够,所以我增加到 100ms 没有办法,当然它起作用,只是感觉有点未定。

val layoutManager = LinearLayoutManager(hostActivity, VERTICAL, false)
fileRv.layoutManager = layoutManager
fileRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
        if (dx == 0 && dy == 0) {
            scrollToLastPosition()
        }
    }

    private fun scrollToLastPosition() {
        val lastScrollPosition = viewModel.consumeLastScrollPosition()
        if (lastScrollPosition > 0) {
            Handler().postDelayed({ layoutManager.scrollToPositionWithOffset(lastScrollPosition, 0) }, 100)
        }
    }
})

override fun onItemClick(position: Int) {
    layoutManager.findFirstVisibleItemPosition().let {
        if (it >= 0) viewModel.markLastScrollPosition(it)
    }
}

fun markLastScrollPosition(position: Int) {
    currentFolderListData.value?.lastOrNull()?.lastScrollPosition = position
}

fun consumeLastScrollPosition(): Int {
    currentFolderListData.value?.lastOrNull()?.run {
        return lastScrollPosition.apply { lastScrollPosition = -1 }
    }
    return 0
}

我找到了解决办法。 因为我是 DNA Launcher 的开发者。当我使用RecyclerView显示A-Z App List时,发现函数scrollToPositionWithOffset不起作用。我跟踪了将近一天的问题,我想通了。

RecyclerView再次显示时,让RecyclerView的parent做requestLayout即可。

对我有用。

而且我知道如何使函数 scrollToPositionWithOffset 不起作用。你只需要在它上面添加一个视图然后让它消失。