How to tell RecyclerView to start at specific item position

前端 未结 6 2131
难免孤独
难免孤独 2021-02-20 10:43

I want my RecyclerView with LinearLayoutManager to show up with scroll position at specific item after adapter got updated. (not first/last position) Means the at first (re-)lay

6条回答
  •  清歌不尽
    2021-02-20 11:39

    I found a solution myself:

    I extended the LayoutManager:

      class MyLayoutManager extends LinearLayoutManager {
    
        private int mPendingTargetPos = -1;
        private int mPendingPosOffset = -1;
    
        @Override
        public void onLayoutChildren(Recycler recycler, State state) {
            if (mPendingTargetPos != -1 && state.getItemCount() > 0) {
                /*
                Data is present now, we can set the real scroll position
                */
                scrollToPositionWithOffset(mPendingTargetPos, mPendingPosOffset);
                mPendingTargetPos = -1;
                mPendingPosOffset = -1;
            }
            super.onLayoutChildren(recycler, state);
        }
    
        @Override
        public void onRestoreInstanceState(Parcelable state) {
            /*
            May be needed depending on your implementation.
    
            Ignore target start position if InstanceState is available (page existed before already, keep position that user scrolled to)
             */
            mPendingTargetPos = -1;
            mPendingPosOffset = -1;
            super.onRestoreInstanceState(state);
        }
    
        /**
         * Sets a start position that will be used as soon as data is available.
         * May be used if your Adapter starts with itemCount=0 (async data loading) but you need to
         * set the start position already at this time. As soon as itemCount > 0,
         * it will set the scrollPosition, so that given itemPosition is visible.
         * @param position
         * @param offset
         */
        public void setTargetStartPos(int position, int offset) {
            mPendingTargetPos = position;
            mPendingPosOffset = offset;
        }
    }
    

    It stores may target position. If onLayoutChildren is called by RecyclerView, it checks if itemCount is already > 0. If true, it calls scrollToPositionWithOffset().

    So I can tell immediately what position should be visible, but it will not be told to LayoutManager before position exists in Adapter.

提交回复
热议问题