drod
drod

Reputation: 369

Android Fragment with FirebaseRecyclerAdapter looses scroll position on rotation

I am using firebase database with firebaseui's FirebaseRecyclerAdapter. I have followed the example here:
https://github.com/firebase/FirebaseUI-Android/tree/master/database -except I'm using a fragment.

The app works fine and I am having no issues except that when the device is rotated the recycler view does not restore its scroll position and instead resets to the top item. - for example user scrolls 8 items down and then rotates device. user should be in the same scroll position, but instead position has returned to top.

I guess I could just put in additional code to handle this and scroll to the correct position, but I know from experience that the RecyclerView should handle this on its own. does the the FirebaseRecyclerAdapter require me to handle this?

Upvotes: 0

Views: 683

Answers (2)

S.Bozzoni
S.Bozzoni

Reputation: 1002

I found also that solution that works fine even in a normal activity

in onCreate:

mDataObserver = new RecyclerView.AdapterDataObserver() {
    @Override
    public void onItemRangeInserted(int positionStart, int itemCount) {
        mLayoutManager.scrollToPositionWithOffset(mRvPositionIndex, 0);
    }
};

myFirebaseRecyclerAdapter.registerAdapterDataObserver(mDataObserver);

don't forget to unregister the AdapterDataObserver.

Upvotes: 0

drod
drod

Reputation: 369

Answering my own question-

The only way I've been able to get this to work is to save state like this:

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    mRvPositionIndex = mLayoutManager.findFirstVisibleItemPosition();
    View startView = mRecyclerView.getChildAt(0);

    mRvTopView = (startView == null) ? 0 : (startView.getTop() - mRecyclerView.getPaddingTop());

    outState.putInt(RV_POS_INDEX, mRvPositionIndex);
    outState.putInt(RV_TOP_VIEW, mRvTopView);
}

and then in onCreateView(), right after I set the adapter I do this

if (savedInstanceState != null) {

        mRvPositionIndex = savedInstanceState.getInt(RV_POS_INDEX);
        mRvTopView = savedInstanceState.getInt(RV_TOP_VIEW);

        mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
            public void onItemRangeInserted(int positionStart, int itemCount) {

                mLayoutManager.scrollToPositionWithOffset(mRvPositionIndex, mRvTopView);
            }
        });
    }

I've done a little testing so far but seems to work fine. If someone has a better solution please let me know.

Upvotes: 1

Related Questions