1

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());
    }
//...

}
alla
  • 529
  • 5
  • 20
  • Possible duplicate of [How to save RecyclerView's scroll position using RecyclerView.State?](http://stackoverflow.com/questions/27816217/how-to-save-recyclerviews-scroll-position-using-recyclerview-state) – Sufian Apr 30 '17 at 08:30

5 Answers5

2

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);
        } 
    } 


} 
Community
  • 1
  • 1
Muhammad Waleed
  • 2,517
  • 4
  • 27
  • 75
1

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 );
    }
}
rafsanahmad007
  • 23,683
  • 6
  • 47
  • 62
  • The result is the same: my screen is empty after rotation. – alla Apr 30 '17 at 07:58
  • 1
    @alla if the screen is empty after rotation, it is because you did not save/restore the contents of your `RecyclerView`. It is not same as the save/restore of the scroll position. – Sufian Apr 30 '17 at 08:31
  • @Sufian you are right, thank you. I had to save my list as well. Now it works – alla Apr 30 '17 at 08:41
  • @Sufian don't you want to write an answer? I'd accept it. – alla Apr 30 '17 at 08:47
  • @alla unfortunately the community here encourages that duplicate questions be marked as duplicates. – Sufian Apr 30 '17 at 10:14
0

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

0

You may store position in shared prefrences and when you restart your app get the values from preferences and populate recycler view accordingly

  • 1. Store scrollposition in sharedpreferences in the onpause/ondestroy of your activity/fragment. 2. Restore scrollposition in onResume. Se other answers for the methods to get scrollposition – Gillis Haasnoot Apr 30 '17 at 08:17
  • This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker – Kenzo_Gilead Apr 30 '17 at 09:07
0

It's important to set adapter with already filled data. In this case the position is restored automatically.

Alexey
  • 440
  • 3
  • 12