0

I have an activity which present a list of items through a RecyclerView. When I click on an item, it goes for another activity to show it. Problem is: when I press the back button on the Action bar it takes me back to the RecyclerView but not at the same scroll position (it takes to the beggining).

What did I try so far?

  1. I have created onPause and onResume methods in order to return back to the same scroll position when I press back key button - failed

  2. I read somewhere that I can implement it by:

    implementation "androidx.recyclerview:recyclerview:1.3.0-alpha01"

and then:

mAdapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY);

it also failed. this is my whole class:

public class ItemsActivity extends AppCompatActivity{

private RecyclerView mRecyclerView;
private ImageAdapter mAdapter;
private FirebaseStorage mStorage;
private DatabaseReference mDatabaseRef;
private ValueEventListener mDBListener;
private List<Item> mItem;


Parcelable state;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_items);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);


    mRecyclerView=findViewById(R.id.mRecyclerView);
    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));  //this was alone


    mItem=new ArrayList<>();
    mAdapter=new ImageAdapter(ItemsActivity.this,mItem);
    mAdapter.setStateRestorationPolicy(RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY);  //added
    mRecyclerView.setAdapter(mAdapter);

    mStorage=FirebaseStorage.getInstance();
    mDatabaseRef= FirebaseDatabase.getInstance().getReference("Item");
    mDBListener = mDatabaseRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            mItem.clear();
            for(DataSnapshot postSnapshot: snapshot.getChildren()){
                Item item = postSnapshot.getValue(Item.class);
                item.setKey(postSnapshot.getKey());
                mItem.add(item);
            }
            Collections.reverse(mItem);     
            mAdapter.notifyDataSetChanged();
        }
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            Toast.makeText(ItemsActivity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
}

@Override
protected void onPause() {

    state = mRecyclerView.getLayoutManager().onSaveInstanceState();
    super.onPause();
}

@Override
protected void onResume() {
    super.onResume();
    mRecyclerView.getLayoutManager().onRestoreInstanceState(state);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mDatabaseRef.removeEventListener(mDBListener);
}}

What should i need to change? Thanks!

Naor P
  • 13
  • 4

1 Answers1

0

You have to use the onSaveInstanceState(Bundle state) and onRestoreInstanceState(Bundle state).

The Layout manager is the one who takes care of the store state and restore it.

protected void onSaveInstanceState(Bundle state) {
     super.onSaveInstanceState(state);

     // Save list state
     mListState = mLayoutManager.onSaveInstanceState();
     state.putParcelable(LIST_STATE_KEY, mListState);
}
protected void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);

    // Retrieve list state and list/item positions
    if(state != null)
        mListState = state.getParcelable(LIST_STATE_KEY);
}
@Override
protected void onResume() {
    super.onResume();

    if (mListState != null) {
        mLayoutManager.onRestoreInstanceState(mListState);
    }
}

PS:In activity instead of onRestoreInstanceState, you can safely do it on onActivityCreated

Narendra_Nath
  • 4,578
  • 3
  • 13
  • 31