代码之家  ›  专栏  ›  技术社区  ›  hsm59

无法使用LayoutManager还原RecyclerView中的滚动位置

  •  0
  • hsm59  · 技术社区  · 7 年前

    因此,我有一个EditText,我在其上设置了一个EditoractionListener,即在用户输入文本并按enter/search后,它将获取详细信息并相应地填充回收器视图。

    现在为了保存配置更改的状态,我编写了以下代码-

    Parcelable stateList;
    
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    
        //Saving instance of the state in Parcelable stateList
        stateList = recyclerView.getLayoutManager().onSaveInstanceState();
        outState.putParcelable(RETAIN_STATE, stateList);
    }
    
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    
        if(savedInstanceState!=null) {
            stateList = savedInstanceState.getParcelable(RETAIN_STATE);
            recyclerView.getLayoutManager().onRestoreInstanceState(stateList);
        }
    }
    

    我正在使用MVP,所以我正在演示者的回调中设置适配器。

    在屏幕旋转后,当我们在键盘上单击enter/search时,我能够保持状态,所以我在onRestoreInstanceState()中尝试了这种黑客攻击,但我认为应该有更好的方法来实现这一点。

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    
        if(savedInstanceState!=null) {
            //The hack!
            et_search.onEditorAction(EditorInfo.IME_ACTION_SEARCH);
            stateList = savedInstanceState.getParcelable(RETAIN_STATE);
            recyclerView.getLayoutManager().onRestoreInstanceState(stateList);
        }
    }
    

    提前谢谢。

    2 回复  |  直到 7 年前
        1
  •  0
  •   akshay_shahane    7 年前

    <activity android:name=".mainpage.view.MainActivity" android:configChanges="orientation|screenSize|screenLayout" >
    

    将其包含在该活动的清单中

    import android.content.Context;
    import android.os.Bundle;
    import android.os.Parcelable;
    import android.support.annotation.Nullable;
    import android.support.v7.widget.RecyclerView;
    import android.util.AttributeSet;
    
    /**
     * Class {@link StatefulRecyclerView} extends {@link RecyclerView} and adds position management on configuration changes.
     *
     * @author FrantisekGazo
     * @version 2016-03-15
     */
    public final class StatefulRecyclerView
            extends RecyclerView {
    
        private static final String SAVED_SUPER_STATE = "super-state";
        private static final String SAVED_LAYOUT_MANAGER = "layout-manager-state";
    
        private Parcelable mLayoutManagerSavedState;
    
        public StatefulRecyclerView(Context context) {
            super(context);
        }
    
        public StatefulRecyclerView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }
    
        public StatefulRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        protected Parcelable onSaveInstanceState() {
            Bundle bundle = new Bundle();
            bundle.putParcelable(SAVED_SUPER_STATE, super.onSaveInstanceState());
            bundle.putParcelable(SAVED_LAYOUT_MANAGER, this.getLayoutManager().onSaveInstanceState());
            return bundle;
        }
    
        @Override
        protected void onRestoreInstanceState(Parcelable state) {
            if (state instanceof Bundle) {
                Bundle bundle = (Bundle) state;
                mLayoutManagerSavedState = bundle.getParcelable(SAVED_LAYOUT_MANAGER);
                state = bundle.getParcelable(SAVED_SUPER_STATE);
            }
            super.onRestoreInstanceState(state);
        }
    
        /**
         * Restores scroll position after configuration change.
         * <p>
         * <b>NOTE:</b> Must be called after adapter has been set.
         */
        private void restorePosition() {
            if (mLayoutManagerSavedState != null) {
                this.getLayoutManager().onRestoreInstanceState(mLayoutManagerSavedState);
                mLayoutManagerSavedState = null;
            }
        }
    
        @Override
        public void setAdapter(Adapter adapter) {
            super.setAdapter(adapter);
            restorePosition();
        }
    }

    Link to gist

        2
  •  0
  •   Ekalips    7 年前

    onRestoreInstanceState LayoutManager中的配置更改,因为它将自动调用(所有视图都具有 onSaveInstanceState onRestoreInstanceState 这是从生命周期所有者那里传来的)。即使你想-你所要做的就是恢复视图的滚动位置。

    RecyclerView 并在屏幕旋转时将其设置回原位。然后再次调用search(或filter,随便什么)。