我有一个Recycler视图,它位于SwipeRefreshLayout内部。此外,还可以打开另一个活动中的每个项目。 返回Recycler后,我需要滚动到所选项目,或前一个Y. 怎么做?
是的,我用Google搜索,在StackOverFlow中找到关于保存布局管理器实例的文章,如下所示:RecyclerView store / restore state between activities。 但是,它对我没有帮助。
更新
现在我有这种解决问题,当然,它也不起作用。
private int scrollPosition;
...//onViewCreated - it is fragment
recyclerView.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(llm);
data = new ArrayList<>();
adapter.setData(getActivity(), data);
recyclerView.setAdapter(adapter);
...
@Override
public void onResume() {
super.onResume();
recyclerView.setScrollY(scrollPosition);
}
@Override
public void onPause() {
super.onPause();
scrollPosition = recyclerView.getScrollY();
}
是的,我尝试过scrollTo(int,int) - 不能工作。
现在我尝试滚动,例如,Y = 100,但它根本没有滚动。
答案 0 :(得分:36)
保存回收视图位置的当前状态@onPause:
positionIndex= llManager.findFirstVisibleItemPosition();
View startView = rv.getChildAt(0);
topView = (startView == null) ? 0 : (startView.getTop() - rv.getPaddingTop());
恢复滚动位置@onResume:
if (positionIndex!= -1) {
llManager.scrollToPositionWithOffset(positionIndex, topView);
}
或其他方式可以是@onPause:
long currentVisiblePosition = 0;
currentVisiblePosition = ((LinearLayoutManager)rv.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
恢复@onResume:
((LinearLayoutManager) rv.getLayoutManager()).scrollToPosition(currentVisiblePosition);
currentVisiblePosition = 0;
答案 1 :(得分:19)
很多这些答案似乎过于复杂化了。
LayoutManager支持onRestoreInstanceState
开箱即用,因此无需保存滚动位置等。内置方法已经保存了像素完美位置。
示例片段代码(为清晰起见,删除了空检查等):
private Parcelable listState;
private RecyclerView list;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
listState=savedInstanceState.getParcelable("ListState");
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("ListState", list.getLayoutManager().onSaveInstanceState());
}
然后打电话
list.getLayoutManager().onRestoreInstanceState(listState);
将您的数据重新附加到RecyclerView
答案 2 :(得分:2)
使用您的回收商视图linearlayoutmanager获取滚动位置
int position = 0;
if (linearLayoutManager != null) {
scrollPosition = inearLayoutManager.findFirstVisibleItemPosition();
}
并在恢复时使用以下代码
if (linearLayoutManager != null) {
cardRecyclerView.scrollToPosition(mScrollPosition);
}
希望这有助于你
答案 3 :(得分:2)
从androidx recyclerView库的1.2.0-alpha02版本开始,现在可以对其进行自动管理。只需添加:
implementation "androidx.recyclerview:recyclerview:1.2.0-alpha02"
并使用:
adapter.stateRestorationPolicy = StateRestorationPolicy.PREVENT_WHEN_EMPTY
StateRestorationPolicy枚举有3个选项:
请注意,在回答此问题时,recyclerView库仍处于alpha03中,但是 alpha阶段不适合用于生产目的。
答案 4 :(得分:0)
要将位置保存到“偏好设置”中,请将其添加到onStop()
int currentVisiblePosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
getPreferences(MODE_PRIVATE).edit().putInt("listPosition", currentVisiblePosition).apply();
然后恢复这样的位置
if (getItemCount() == 0) {
int savedListPosition = getPreferences(MODE_PRIVATE).getInt("listPosition", 0);
recyclerView.getLayoutManager().scrollToPosition(savedListPosition); }
这最后一个代码应添加到Adapter事件中(不确定女巫事件,但在我的情况下是onEvent()-com.google.firebase.firestore.EventListener)
答案 5 :(得分:0)
由于某些原因,关于如何在方向更改时如何保存和恢复your_scrolling_container中的滚动位置,存在很多令人误解的提示/建议。
获取当前滚动位置并将其保存在Activity的onSaveInstanceState中 扩展某个可滚动视图以在此处执行相同操作 防止活动在旋转时被破坏 是的,他们工作正常,但是……
但是实际上,一切都简单得多,因为Android已经为您完成了!
如果您仔细看一下 在RecyclerView / ListView / ScrollView / NestedScrollView源中,您将看到每个源都将其滚动位置保存在onSaveInstanceState中。并且在第一次布局传递期间,他们正尝试在onLayout方法中滚动到该位置。
只需要做两件事,以确保它可以正常运行:
为您的可滚动视图设置ID,这可能已经完成。否则,Android将无法自动保存视图状态。
在第一次布局通过之前提供数据,以具有与旋转之前相同的滚动边界。这是开发人员通常遇到一些问题的步骤。
答案 6 :(得分:0)
我发现的最简单且与过渡兼容的方法是:
@Override
public void onPause() {
super.onPause();
recyclerView.setLayoutFrozen(true);
}
@Override
public void onResume() {
super.onResume();
recyclerView.setLayoutFrozen(false);
}
答案 7 :(得分:-1)
您可以使用scrollToPosition
或smoothScrollToPosition
滚动到RecyclerView 中的任何项目位置。
如果要滚动到适配器中的项目位置,则必须使用适配器scrollToPosition
或smoothScrollToPosition
。