Сохранение положения прокрутки RecyclerView

У меня есть активность с ViewPager и 3 фрагментами, называемыми A, B, C. A имеет recyclerView, заполненный cardView, и каждая карта реализует и OnClickListener, что приводит к новому действию D. Я хочу иметь возможность сохранять положение прокрутки recyclerView при переключении вкладок и при возврате из открытого действия D.

то, что я сделал до сих пор во фрагменте 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, поэтому блок выполняется (и это означает, что saveRecyclerViewState не равен нулю), но recyclerView всегда начинается с первой карты, несмотря ни на что. Также, когда я открываю новое действие, щелкнув карту, а затем возвращаюсь к фрагменту A, я получаю уведомление Toast о том, что состояние сохраняется, но не то, что в onViewRestored. Насколько я понимаю, в основном происходит то, что состояние моего linearLayoutManager сохраняется, но затем мне почему-то не удается передать информацию для восстановления позиции прокрутки. Что я делаю не так ?

РЕШЕНО: решил это сам, но это может помочь кому-то в будущем. TL; DR -> просто объявите адаптер в onCreateView, а затем вызовите yourRecyclerView.setAdapter(yourAdapter) как в OnCreateView, так и в OnResume(), остальная часть кода остается прежней

Что случилось потом ? Достаточно просто, я правильно сохранял состояние linearLayoutManager в onSavedInstanceState(), а затем правильно восстанавливал его в OnCreate, но я не смог заметить никакой разницы, поскольку сохраненное состояние состояния «перезаписывалось», устанавливая мой адаптер в OnStart. По шагам:
1) действие фрагмента вызывает onSavedInstanceState и сохраняет LinearLayoutManager моего RecyclerView в Parcelable.
2) приложение возвращается к фрагменту и вызывает onViewStateRestored()/OnCreateView(), там мы читаем из пакета и восстановите наш recyclerViewState
3)Теперь проблема вызывается OnStart(), и, конечно же, именно здесь объявляется мой адаптер, а затем устанавливается в recyclerView. Теперь старый recyclerView (с сохраненным состоянием) удален и заменен новым новым recyclerView без записи предыдущего.

Таким образом, просто установив адаптер в методе OnResume(), вы решу проблему. Я думаю, вы также можете решить эту проблему, оставив код в OnStart(), сохранив состояние старого recyclerView и затем передав его новому recyclerView в конце OnStart(). но это не очень чистое решение


comment
stackoverflow.com/a/29166336/3503855   -  person Anis LOUNIS    schedule 20.02.2017
comment
И это именно то, что я делаю, если вы читаете код, но он не работает   -  person Davide Valiante    schedule 20.02.2017