简体   繁体   English

RecyclerView 上 LinearLayoutManager 的 scrollToPositionWithOffset 不起作用

[英]scrollToPositionWithOffset from LinearLayoutManager on RecyclerView not working

I'm trying to make an horizontal list of sticky images with RecyclerView and I'd like to move them by pixels' offset with scrollToPositionWithOffset .我正在尝试使用RecyclerView制作一个水平的粘性图像列表,我想使用scrollToPositionWithOffset按像素偏移量移动它们。 I thought passing 0 as position and the pixels I want to move to right / left as offset .我想传递0作为position和我想移动到右/左的像素作为offset

But it doesn't work, the list remains untouched, unscrolled, it doesn't move.但它不起作用,列表保持不变,未滚动,它不会移动。 This is my implementation:这是我的实现:

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) {

    }
});

what am I doing wrong?我究竟做错了什么?

Thank you very much.非常感谢你。

Regards.问候。

Rafael.拉斐尔。

I finally used: 我终于用了:

recyclerView.scrollBy(int offsetX, int offsetY); setting offsetY = 0 and it works now. 设置offsetY = 0

I don't understand what's the utility of the function scrollToPositionWithOffset . 我不明白函数scrollToPositionWithOffset的用途是什么。

I had a similar issue. 我有一个类似的问题。 My problem was that my recyclerview wasn't of the same size of its parent layout. 我的问题是我的recyclerview的父布局大小不一样。 I solved it by setting the recycler view width and height to match_parent . 我通过将回收站视图的宽度和高度设置为match_parent解决了这一问题。 I don't know why this happens in this case. 我不知道为什么在这种情况下会发生这种情况。

A late answer to your first question, and an addition to your answer: 第一个问题的较晚答案,以及答案的补充:

Your method works better for your personal needs, because scrollToPositionWithOffset is not intended to do what you want. 您的方法可以更好地满足您的个人需求,因为scrollToPositionWithOffset不能满足您的要求。

As the doc says here : 正如文档在这里说的那样

[...]Resolved layout start depends on [...] getLayoutDirection(android.view.View) [...] [...]已解决的布局开始取决于[...] getLayoutDirection(android.view.View)[...]

Which means it would offset the scroll target position in the layout direction, vertically in your case. 这意味着它将在您的情况下沿布局方向垂直偏移滚动目标位置。

I don't understand what's the utility of the function scrollToPositionWithOffset. 我不明白函数scrollToPositionWithOffset的用途是什么。

it allows to not only scroll to a given item in the list, but also position it at a more "visible" or otherwise convenient place. 它不仅可以滚动到列表中的给定项目,还可以将其放置在更“可见”或其他方便的位置。

recently I encountered this problem too, I invoke scrollToPositionWithOffset when onScrolled() directly, but nothing change, with that I turn to scrollToPosition() even scrollBy() but not help, finally I attempt to delay that so it work, first time I delay 50ms, but two weeks later I found that's not enough, so I increase to 100ms with no approachs in my hands, of course it work, just feel a little unsettled.最近我也遇到了这个问题,我在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
}

I find a solution.我找到了解决办法。 Coz I am the developer of DNA Launcher.因为我是 DNA Launcher 的开发者。 When I use RecyclerView to display AZ App List, I found that the function scrollToPositionWithOffset is not working.当我使用RecyclerView显示AZ App List时,发现function scrollToPositionWithOffset不工作了。 I track the problem for almost one day and I figured it out.我跟踪了将近一天的问题,然后我弄明白了。

When the RecyclerView display again, just let the parent of RecyclerView do requestLayout.当RecyclerView再次显示时,只要让RecyclerView的parent做requestLayout即可。

It works for me.这个对我有用。

And I know how to make the function scrollToPositionWithOffset not working.而且我知道如何使 function scrollToPositionWithOffset 不起作用。 You just need to add a view on it and make it gone then.你只需要在它上面添加一个视图然后让它消失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM