我正在用gridlayoutManager填充recyclerView。现在,我想在屏幕旋转上保存滚动位置。
我尝试使用onSaveInstanceState和onRestoreInstanceState()这样做 下面是我的代码:
@Override
protected void onSaveInstanceState(Bundle outState) {
Log.e(TAG, "onSaveInstanceState");
super.onSaveInstanceState(outState);
outState.putParcelable(KEY_INSTANCE_STATE_RV_POSITION,
gridLayoutManager.onSaveInstanceState());
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.e(TAG, "onRestoreInstanceState");
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState!= null){
Parcelable savedState =
savedInstanceState.getParcelable(KEY_INSTANCE_STATE_RV_POSITION);
movieAdapter.addAll(movieItemList);
if (savedState!= null){
gridLayoutManager.onRestoreInstanceState(savedState);
}
}
}
//this is my movieAdapter.addAll() method
public void addAll(List<MovieItem>items){
movieItems = items;
}
//This is the method to get lists of movies from ViewModel Class
private void loadFavMovies() {
FavViewModel favViewModel =
ViewModelProviders.of(MainActivity.this).get(FavViewModel.class);
favViewModel.getFavListLiveData().observe(MainActivity.this, new
Observer<List<FavlistItem>>() {
@Override
public void onChanged(List<FavlistItem> favlistItems) {
if (!favlistItems.isEmpty()) {
loadingIndicator.setVisibility(View.GONE);
movieRecycler.setVisibility(View.GONE);
favRecycler.setVisibility(View.VISIBLE);
favAdapter.setFavlistItems(favlistItems);
Toast.makeText(getApplicationContext(), "Swipe Left Or
Right To remove Item",Toast.LENGTH_SHORT).show();
}else {
loadingIndicator.setVisibility(View.GONE);
Toast.makeText(getApplicationContext(), "No Favorite
Movies",Toast.LENGTH_SHORT).show();
}
}
});
}
这是此项目https://github.com/harshabhadra/Movies-Mela的GitHub链接
答案 0 :(得分:3)
我知道我迟到了,但如果它有帮助的话!
存储回收站视图位置比其他答案看起来要简单得多
你可以这样做
先创建一个成员变量
Parcelable state;
现在
@Override
protected void onPause() {
super.onPause();
state = recyclerView.getLayoutManager().onSaveInstanceState();
}
@Override
protected void onResume() {
super.onResume();
recyclerView.getLayoutManager().onRestoreInstanceState(state);
}
使用上面的代码覆盖暂停和恢复方法,你就可以开始了!!
答案 1 :(得分:2)
现在,它有简单的解决方案。使用此依赖项
implementation "androidx.recyclerview:recyclerview:1.2.0-alpha05"
然后像下面一样设置stateRestorationPolicy
myAdapter.stateRestorationPolicy=RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY
答案 2 :(得分:1)
做到这一点的一种方法是停止在方向改变时重新创造活动。您可以将其添加到清单中的活动中。
android:configChanges="orientation|screenSize"
但这并不总是一个好习惯,因此另一种选择是保存适配器位置,然后退出onSaveInstanceState
,然后使用onCreate
滚动到scrollToPosition
中的位置。因此,例如,您将按照以下方式进行操作。
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("position", mRecyclerView.getAdapterPosition()); // get current recycle view position here.
//your other code
super.onSaveInstanceState(savedInstanceState);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//your other code
if(savedInstanceState != null){
// scroll to existing position which exist before rotation.
mRecyclerView.scrollToPosition(savedInstanceState.getInt("position"));
}
}
答案 3 :(得分:0)
实现您想要获得的最简单的方法是在Fragment中而不是直接在Activity中使用RecyclerView。
与活动不同,默认情况下,片段不会在旋转时重新创建,但会保留其状态。这样,recyclerview将始终保持在相同的滚动位置。
我正在其中一个应用程序中以这种方式使用RecyclerView,该应用程序显示包含200多个元素的列表。
答案 4 :(得分:0)
如果您使用0
的子类GridLayoutManager
,则滚动位置应该已经自动保存。您可以查看LinearLayoutManager
内的SavedState
:
LinearLayoutManager
public static class SavedState implements Parcelable {
int mAnchorPosition;
int mAnchorOffset;
boolean mAnchorLayoutFromEnd;
实际上是您的滚动位置,并且在旋转过程中已保存。如果这对您不起作用,则可能是其他原因:例如,您可能错误地重新加载/重新应用了数据。这可能是您需要提出的真正问题。您可能需要将该数据缓存在某处,以便在配置更改后立即自动重新应用。
我还可以确认在我使用过mAnchorPosition
和LinearLayoutManager
的每个项目中有什么价值,在旋转过程中可以正确保持滚动位置,而无需我做任何额外的工作。
答案 5 :(得分:0)
我已经尝试了所有人提出的所有建议,但是最后,这项要点对我来说有用
https://gist.github.com/FrantisekGazo/a9cc4e18cee42199a287
我只是将其导入到我的项目中,并用此替换默认提供的recyclerView “ StateFulRecyclerView”解决了我的问题,并在屏幕旋转或任何配置更改期间自动处理滚动位置。无需使用onSaveInstanceState来维护滚动位置。
答案 6 :(得分:0)
很简单。保存暂停时的位置,恢复时恢复。
ON 暂停
lastVisitPosition = ((LinearLayoutManager)recycleView.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
onResume
((LinearLayoutManager) recycleView.getLayoutManager()).scrollToPosition(lastVisitPosition);
或
((LinearLayoutManager) recycleView.getLayoutManager()).scrollToPositionWithOffset(lastVisitPosition,0)