保存RecyclerView滚动位置

时间:2017-02-20 15:18:47

标签: android android-fragments android-recyclerview fragmentstatepageradapter android-savedstate

我有一个带有ViewPager的活动和3个叫做A,B,C的片段。 A有一个由cardView填充的recyclerView,每个卡都实现,OnClickListener导致一个新的Activity D.我希望能够在切换选项卡时以及从打开的活动D返回时保存recyclelerView滚动位置。

到目前为止,我在片段A中做了什么(包含RecyclerView的那个看起来像这样:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    recyclerView = (RecyclerView)inflater.inflate(R.layout.event_fragment_layout, container,false);

    linearLayoutManager = new LinearLayoutManager((getActivity()));
    recyclerView.setLayoutManager(linearLayoutManager);
    recyclerView.setHasFixedSize(true);

    return recyclerView;

}

public void onStart(){
//This is where my adapter is created and attached to the recyclerView
recyclerView.setAdapter(myadapter)

 }

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

    outState.putParcelable(RECYCLER_STATE,linearLayoutManager.onSaveInstanceState());
    String saved = linearLayoutManager.onSaveInstanceState().toString();
    Toast.makeText(getContext(),"Saving Instance State",Toast.LENGTH_SHORT).show();
    Log.d("SAVE_CHECK ", saved);
}


@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {

    if(savedInstanceState!=null) {

        Parcelable savedRecyclerViewState = savedInstanceState.getParcelable(RECYCLER_STATE);
        if(savedRecyclerViewState!=null) {
            linearLayoutManager.onRestoreInstanceState(savedRecyclerViewState);
            Toast.makeText(getContext(), "Restoring Instance State", Toast.LENGTH_SHORT).show();
        }
        else{
            Toast.makeText(getContext(), "SAVED STATE IS NULL", Toast.LENGTH_SHORT).show();

        }

    }
    super.onViewStateRestored(savedInstanceState);
}

我正在显示Toast,因此块正在执行(这意味着savedRecyclerViewState不为null)但是recyclelerView始终从第一张Card开始,无论如何。此外,当我通过点击一张卡打开一个新的活动,然后回到片段A我得到Toast通知状态正在保存但不是onViewRestored中的状态。 根据我的理解,基本上发生的是我的linearLayoutManager的状态得到了保存,但后来我无法通过信息来恢复滚动位置。我做错了什么?

已解决:我自己解决了这个问题,但这可能对未来有所帮助。 TL; DR - >只需在onCreateView中声明适配器然后调用     在OnCreateView和OnResume()中的yourRecyclerView.setAdapter(yourAdapter),其余代码保持不变

那时发生了什么?简单地说,我正确地在onSavedInstanceState()中正确保存linearLayoutManager状态,然后在OnCreate中正确恢复它,但我无法发现它有任何区别,因为通过在OnStart中设置我的适配器来“覆盖”保存的状态。 步骤:
1)片段活动调用onSavedInstanceState并将RecyclerView的LinearLayoutManager保存为Parcelable。
2)应用程序返回到片段并调用onViewStateRestored()/ OnCreateView(),我们从parcelable中读取并恢复我们的recyclerViewState
3)现在问题 OnStart()被调用,当然这是我的适配器被声明然后设置为recyclerView的地方。现在,旧的recyclerView(具有保存状态的那个)已经消失,并被一个全新的RecyclerView替换,没有前一个的记录。

因此,只需在OnResume()方法中设置适配器即可解决问题。 我想你也可以通过将代码保留在OnStart()中来存储旧的recyclerView 状态,然后将其传递给OnStart()末尾的 new recyclerView 来解决它。但这不是一个非常干净的解决方案

0 个答案:

没有答案