问题
Can't restore the scroll posiotn of RecyclerView after rotation and after I close the app and open it again. In the first case I could use android:configChanges
in Manifest, but it doesn't help after I reopen the app.
Here is my code. After trying restore the state I see an empty screen without my list.
public class MainActivity extends AppCompatActivity implements IMainContract.View {
private final String BUNDLE_RECYCLER_LAYOUT = MainActivity.class.getSimpleName() + ".save.state.list";
private IMainContract.Presenter mainPresenter;
private MainAdapter adapter;
private LinearLayoutManager layoutManager;
private ImageView ivRefresh;
private ProgressBar progressBar;
private RecyclerView rvUsers;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ivRefresh = (ImageView) findViewById(R.id.ivRefresh);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
rvUsers = (RecyclerView) findViewById(R.id.rvUsers);
layoutManager = new LinearLayoutManager(this);
rvUsers.setLayoutManager(layoutManager);
mainPresenter = new MainPresenter(Repository.getInstance(this), this);
adapter = new MainAdapter(new ArrayList<>(), this);
rvUsers.setAdapter(adapter);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ivRefresh.setOnClickListener(v -> mainPresenter.onRefreshPressed());
if (savedInstanceState != null) {
Parcelable savedRecyclerLayoutState = savedInstanceState.getParcelable(BUNDLE_RECYCLER_LAYOUT);
layoutManager.onRestoreInstanceState(savedRecyclerLayoutState);
} else {
mainPresenter.subscribe();
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(BUNDLE_RECYCLER_LAYOUT, layoutManager.onSaveInstanceState());
}
//...
}
回答1:
You need to follow this answer on stackoverflow.Change your code
public class MainActivity extends AppCompatActivity {
private final String KEY_RECYCLER_STATE = "recycler_state";
private MainAdapter adapter;
private LinearLayoutManager layoutManager;
private ImageView ivRefresh;
private ProgressBar progressBar;
private RecyclerView rvUsers;
private static Bundle mBundleRecyclerViewState;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ivRefresh = (ImageView) findViewById(R.id.ivRefresh);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
rvUsers = (RecyclerView) findViewById(R.id.rvUsers);
layoutManager = new LinearLayoutManager(this);
rvUsers.setLayoutManager(layoutManager);
adapter = new MainAdapter(new ArrayList<>(), this);
rvUsers.setAdapter(adapter);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
protected void onPause()
{
super.onPause();
// save RecyclerView state
mBundleRecyclerViewState = new Bundle();
Parcelable listState = rvUsers.getLayoutManager().onSaveInstanceState();
mBundleRecyclerViewState.putParcelable(KEY_RECYCLER_STATE, listState);
}
@Override
protected void onResume()
{
super.onResume();
// restore RecyclerView state
if (mBundleRecyclerViewState != null) {
Parcelable listState = mBundleRecyclerViewState.getParcelable(KEY_RECYCLER_STATE);
rvUsers.getLayoutManager().onRestoreInstanceState(listState);
}
}
}
回答2:
You need to override the onRestoreInstanceState()
and set recyclerView.getLayoutManager()
with the saved bundle
Parcelable savedRecyclerLayoutState ;
@Override
public void onRestoreInstanceState(@Nullable Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if(savedInstanceState != null)
{
savedRecyclerLayoutState = savedInstanceState.getParcelable(BUNDLE_RECYCLER_LAYOUT);
rvUsers.getLayoutManager().onRestoreInstanceState(savedRecyclerLayoutState);
}
}
Also you need to override onResume()
in your activity
@Override
protected void onResume() {
super.onResume();
if (savedRecyclerLayoutState != null) {
layoutManager.onRestoreInstanceState(savedRecyclerLayoutState );
}
}
回答3:
Initially you have to get the current scrolling position of the RecyclerView by calling:
int index = rvUsers.getFirstVisiblePosition();
Then you have to save this value while orientation changes and when the RecyclerView is created again you have to move your RecyclerView to this index.
I suppose this could work:
rvUsers.smoothScrollToPosition(int index)
if you're using older versions use
setSelection(int position)
and
getFirstVisiblePosition()
methods
回答4:
You may store position in shared prefrences and when you restart your app get the values from preferences and populate recycler view accordingly
回答5:
It's important to set adapter with already filled data. In this case the position is restored automatically.
来源:https://stackoverflow.com/questions/43704113/cant-restore-scroll-position-after-rotation-recyclerview