GridLayoutManager получает неправильную позицию привязки (всегда 0) для состояния сохранения, поэтому позиция прокрутки не может быть сохранена / восстановлена ​​правильно - PullRequest
0 голосов
/ 20 мая 2018

Я пытаюсь использовать этот учебник https://panavtec.me/retain-restore-recycler-view-scroll-position (который я уже успешно использовал в других проектах), чтобы восстановить состояние прокрутки RecyclerView во фрагменте после изменения ориентации.Само сохранение и восстановление работает, данные есть ... но, похоже, это неправильно.Я отладил его и при сохранении в onSaveInstanceState фрагмента ...

public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Parcelable rvState = mRecyclerView.getLayoutManager().onSaveInstanceState();
        outState.putParcelable(INSTANCE_STATE_RV_STATE, rvState);
        outState.putParcelableArrayList(INSTANCE_STATE_ENTRIES, (ArrayList<? extends Parcelable>) mAdapter.getViewItems());
    }

... Я исследовал rvState и сравнил его с состоянием, которое получаю в другом приложении, где сохранение состояния прокрутки в RecyclerView (хотя в действии ...) работал как задумано.

Я знаю, что эти значения из отладчика не слишком помогут, но я вижу, что для приложения, где он работает, я получаю saveInstanceState в onCreateэто показывает смещение привязки и положение привязки, оба! = 0, в отладчике.При восстановлении этого состояния в RecyclerView состояние прокрутки корректно восстанавливается.

В приложении с фрагментом состояние сохранения менеджера макета показывает эти значения как 0 в отладчике (независимо от того, как далеко я прокручиваю вниз), не только при восстановлении, но уже при сохранении.Так что для меня это выглядит так, как будто положение прокрутки (или положение привязки) не может быть правильно определено.Поэтому, конечно, при восстановлении этого состояния оно никуда не прокручивается.

В обоих случаях я использую GridLayoutManager.

Что-то очевидно, что я делаю неправильно или я забыл?Я не совсем уверен, какой код отправлять, потому что кажется, что все очень просто ...

Я добавляю фрагмент в onCreate действия, используя SupportFragmentManger, но только если нет сохраненного состояния экземпляра, чтобычтобы не перезаписывать существующий фрагмент.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if(savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.fl_container, MyFragment.newInstance())
                .commit();
    }
}

Во фрагменте я сохраняю состояние в onSaveInstanceState (см. первый опубликованный метод) и восстанавливаю его в onCreateView

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.fragment_entries, container, false);

    mRecyclerView = v.findViewById(R.id.rv_entries);
    mProgressBar = v.findViewById(R.id.pb_loading);

    RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getContext(), getSpanCount(), LinearLayoutManager.VERTICAL, false);

    mAdapter = new MyAdapter(this);
    mRecyclerView.setLayoutManager(layoutManager);
    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setAdapter(mAdapter);

    if(savedInstanceState != null) {
        mSavedEntries = savedInstanceState.getParcelableArrayList(INSTANCE_STATE_ENTRIES);
        mRecyclerViewState = savedInstanceState.getParcelable(INSTANCE_STATE_RV_STATE);

        if (mSavedEntries != null) {
           mAdapter.setViewItems(mSavedEntries);
        }

        if(mRecyclerViewState != null) {
            layoutManager.onRestoreInstanceState(mRecyclerViewState);
        }
    }

    (...)

    return v;
}

Любая подсказка будетпризнателен ...

РЕДАКТИРОВАТЬ: Поскольку Cheticamp спросил: версия, которую я использую, как заявлено в моем файле Gradle, recyclerview-v7: 26.1.0 и когдаЯ удаляю все элементы состояния сохранения экземпляра, RecyclerView не восстанавливает свое состояние самостоятельно.Я также попытался оставить только ту часть, которая восстанавливает записи.Это тоже ничего не меняет.

...