Abb*_*bas 26 android android-recyclerview linearlayoutmanager
我已经实现了水平滚动RecyclerView
.我RecyclerView
使用了LinearLayoutManager
,而我面临的问题是,当我尝试使用scrollToPosition(position)
或smoothScrollToPosition(position)
或LinearLayoutManager
的scrollToPositionWithOffset(position)
.对我来说都不适用.滚动调用不会滚动到所需位置,也不会调用OnScrollListener
.
到目前为止,我已经尝试了很多不同的代码组合,我不能在这里发布它们.以下是对我有用的(但只是部分):
public void smoothUserScrollTo(final int position) {
if (position < 0 || position > getAdapter().getItemCount()) {
Log.e(TAG, "An attempt to scroll out of adapter size has been stopped.");
return;
}
if (getLayoutManager() == null) {
Log.e(TAG, "Cannot scroll to position a LayoutManager is not set. " +
"Call setLayoutManager with a non-null layout.");
return;
}
if (getChildAdapterPosition(getCenterView()) == position) {
return;
}
stopScroll();
scrollToPosition(position);
if (lastScrollPosition == position) {
addOnLayoutChangeListener(new OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (left == oldLeft && right == oldRight && top == oldTop && bottom == oldBottom) {
removeOnLayoutChangeListener(this);
updateViews();
// removing the following line causes a position - 3 effect.
scrollToView(getChildAt(0));
}
}
});
}
lastScrollPosition = position;
}
@Override
public void scrollToPosition(int position) {
if (position < 0 || position > getAdapter().getItemCount()) {
Log.e(TAG, "An attempt to scroll out of adapter size has been stopped.");
return;
}
if (getLayoutManager() == null) {
Log.e(TAG, "Cannot scroll to position a LayoutManager is not set. " +
"Call setLayoutManager with a non-null layout.");
return;
}
// stopScroll();
((LinearLayoutManager) getLayoutManager()).scrollToPositionWithOffset(position, 0);
// getLayoutManager().scrollToPosition(position);
}
Run Code Online (Sandbox Code Playgroud)
我选择了scrollToPositionWithOffset()
因为这个,但情况可能不同,因为我使用LinearLayoutManager而不是GridLayoutManager.但是这个解决方案对我也有用,但正如我之前所说的那样,只是部分解决了.
如果有人找到了解决方法我会欣赏它.这是我的自定义代码的要点ReyclerView
.
Rob*_*yai 42
几个星期前我遇到了同样的问题,发现只有一个非常糟糕的解决方案.不得不postDelayed
用200-300ms.
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
yourList.scrollToPosition(position);
}
}, 200);
Run Code Online (Sandbox Code Playgroud)
如果您找到了更好的解决方案,请告诉我们!祝好运!
小智 15
结果我在使用之前遇到了类似的问题
myRecyclerview.scrollToPosition(objectlist.size()-1)
Run Code Online (Sandbox Code Playgroud)
当只放入对象列表大小时,它总是保持在顶部.直到我决定将大小设置为变量.再次,这不起作用.然后我假设它可能是在没有告诉我的情况下处理一个outofboundsexception.所以我把它减去1.然后就可以了.
Har*_*nan 14
接受的答案会起作用,但也可能会中断。此问题的主要原因是当您要求它滚动时,回收器视图可能尚未准备好。最好的解决方案是等待回收器视图准备好然后滚动。幸运的是 android 提供了一个这样的选项。以下解决方案适用于 Kotlin,您可以尝试同样的 java 替代方案,它会起作用。
newsRecyclerView.post {
layoutManager?.scrollToPosition(viewModel.selectedItemPosition)
}
Run Code Online (Sandbox Code Playgroud)
post runnable 方法可用于每个 View 元素,并且会在视图准备好后执行,从而确保代码在需要时准确执行。
LinearSmoothScroller
在我的情况下,您每次都可以使用它:
Run Code Online (Sandbox Code Playgroud)LinearSmoothScroller smoothScroller=new LinearSmoothScroller(activity){ @Override protected int getVerticalSnapPreference() { return LinearSmoothScroller.SNAP_TO_START; } };
Run Code Online (Sandbox Code Playgroud)smoothScroller.setTargetPosition(pos); // pos on which item you want to scroll recycler view recyclerView.getLayoutManager().startSmoothScroll(smoothScroller);
完毕。
我也遇到了类似的问题(当列表更新时必须滚动到顶部),但上述选项都没有 100% 有效
不过,我终于在https://dev.to/aldok/how-to-scroll-recyclerview-to-a-certain-position-5ck4 存档链接找到了一个可行的解决方案
scrollToPosition
似乎只有在底层数据集准备好时才有效。
因此,它postDelay
可以(随机)工作,但这取决于设备/应用程序的速度。如果超时太短,则会失败。smoothScrollToPosition
也仅在适配器不忙时有效。
要观察数据集何时准备好,AdapterDataObserver
可以添加 a 并重写某些方法。
解决我的问题的代码:
adapter.registerAdapterDataObserver( object : RecyclerView.AdapterDataObserver() {
override fun onItemRangeInserted(
positionStart: Int,
itemCount: Int
) {
// This will scroll to the top when new data was inserted
recyclerView.scrollToPosition(0)
}
}
Run Code Online (Sandbox Code Playgroud)
所以对我来说问题是我在NestedScrollView 中有一个RecyclerView。我花了一些时间才弄清楚这是问题所在。对此的解决方案是(Kotlin):
val childY = recycler_view.y + recycler_view.getChildAt(position).y
nested_scrollview.smoothScrollTo(0, childY.toInt())
Run Code Online (Sandbox Code Playgroud)
Java(归功于 Himagi /sf/answers/3525751841/)
float y = recyclerView.getY() + recyclerView.getChildAt(selectedPosition).getY();
scrollView.smoothScrollTo(0, (int) y);
Run Code Online (Sandbox Code Playgroud)
诀窍是将嵌套的滚动视图滚动到 Y 而不是 RecyclerView。这在 Android 5.0 Samsung J5 和带有 Android 9 的华为 P30 pro 上运行良好。
这些方法似乎都不适合我。只有下面的一行代码有效
((LinearLayoutManager)mRecyclerView.getLayoutManager()).scrollToPositionWithOffset(adapter.currentPosition(),200);
Run Code Online (Sandbox Code Playgroud)
第二个参数指的是offset,实际上是item view的起始边缘与RecyclerView的起始边缘之间的距离(以像素为单位)。我为它提供了一个常量值,以使顶部的项目也可见。
在此处查看更多参考
归档时间: |
|
查看次数: |
31188 次 |
最近记录: |