无法使用LayoutManager在RecyclerView中恢复滚动位置

时间:2017-07-31 08:56:16

标签: java android android-recyclerview mvp linearlayoutmanager

所以,我有一个EditText,我在其上设置了onEditorActionListener,即在用户输入文本并按下回车/搜索后,它将获取详细信息并相应地填充回收站视图。

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

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

但是当我运行它并旋转屏幕时,回收器视图不会从stateList parcelable恢复状态。

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

当我们在屏幕旋转后点击键盘上的输入/搜索时,我能够保持状态,所以我在onRestoreInstanceState()中尝试了这个hack,但我认为应该有一个更好的方法来解决这个问题。

@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 个答案:

答案 0 :(得分:0)

您真的不需要在LayoutManager中调用onRestoreInstanceState配置更改,因为它会被自动调用(所有视图都有onSaveInstanceStateonRestoreInstanceState从生命周期所有者传递)。即使你想要 - 所有你将实现这一点是恢复视图的滚动位置。

您实际需要做的是保存RecyclerView适配器中设置/使用的数据,并在旋转屏幕时将其设置回来。然后再次调用搜索(或过滤,等等)。

答案 1 :(得分:0)

  

如果不想要通过覆盖配置更改等任何自定义内容,你可以让android为你处理方向更改。等等。

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

在此活动的清单中包含此内容   为了在旋转时在recyler视图中保存滚动位置,您可以使用以下要点来避免重复代码,因为您可以在项目中使用此自定义Recyclerview,只要需要相同的功能

&#13;
&#13;
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();
    }
}
&#13;
&#13;
&#13;

Link to gist

相关问题