4

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

到目前为止我在 Fragment 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 不为空),但无论如何,recyclerView 总是从第一张卡片开始。此外,当我通过单击卡片打开一个新活动然后返回片段 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() 结束时将其传递给新的 recyclerView但这不是一个真正干净的解决方案

4

0 回答 0