BottomNavigationView + сохранение состояний фрагмента при переходе на разные вкладки - PullRequest
0 голосов
/ 01 ноября 2019

Я использую BottomNavigationView для нижних вкладок.

1) Tab 1 - получает данные с сервера и отображает на RecyclerView
2) Tab 2 - получает URL-адрес с сервера и загружает Webview
3) Tab 3 - получаетданные с сервера и отображаются на RecyclerView
4) Вкладка 4 - Экран настройки с использованием PreferenceFragmentCompat

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

Сохранить Fragment.SavedState в SparseArray<Fragment.SavedState>

Fragment.State currentFragmentState = getSupportFragmentManager().saveFragmentInstanceState(currentFragment)

Восстановить состояние снова, когда пользователь вернется к предыдущим вкладкам

fragment.setInitialSavedState(savedState)

getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.container_fragment, fragment, tag)
        .commit();

Что я вижу, так это то, что только вкладка 4 (экран настроек с PreferenceFragmentCompat) поддерживает состояние. Если прокрутить вниз до 10-го элемента и снова вернуться к экрану настроек после перехода к другим фрагментам, я вижу 10-ю позициюнаверху.

Однако первые три вкладки снова вызывают вызовы веб-службы, и все перезагружается. Кроме того, я вижу, что параметр Bundle savedInstanceState метода onCreateView также не равен нулю для первых трех вкладок.

Мои вопросы

1)Как PreferenceFragmentCompat (4-я вкладка) автоматически восстанавливает состояние?
2) Как я могу использовать ненулевой Bundle savedInstanceState (параметр метода onCreateView) в первых трех вкладках и восстанавливать состояния, как если бы4-ая вкладка работает?
3) Почему первые три вкладки не восстанавливают состояния автоматически?

РЕДАКТИРОВАТЬ

Я использую тот же код, что и блог делает.

bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {

                switch (item.getItemId()) {

                    case R.id.navigation_item_1:                       
                        swapFragments(new Fragment1(), item.getItemId(), TAG_1);
                        return true;

                    case R.id.navigation_item_2:      
                        swapFragments(new Fragment2(), item.getItemId(), TAG_2);
                        return true;

                    case R.id.navigation_item_3:
                        swapFragments(new Fragment3(), item.getItemId(), TAG_3);
                        return true;

                    case R.id.navigation_item_4:
                        swapFragments(new Fragment4(), item.getItemId(), TAG_4);
                        return true;

                    default:
                        return false;
                }
            }
        });

        private void swapFragments(Fragment fragment, int itemId, String tag) {
            if (getSupportFragmentManager().findFragmentByTag(tag) == null) {
                saveFragmentState(itemId, tag);
                createFragment(fragment, itemId, tag);
            }
        }

        private void saveFragmentState(int itemId, String tag) {
            Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.container_fragment);
            if (currentFragment != null) {
                fragmentStateArray.put(currentSelectedItemId, getSupportFragmentManager().saveFragmentInstanceState(currentFragment));
            }

            currentSelectedItemId = itemId;
        }

        private void createFragment(Fragment fragment, int itemId, String tag) {
            fragment.setInitialSavedState(fragmentStateArray.get(itemId));

            getSupportFragmentManager()
                    .beginTransaction()
                    .replace(R.id.container_fragment, fragment, tag)
                    .commit();
        }

Ответы [ 2 ]

1 голос
/ 01 ноября 2019

То, что вы делаете прямо сейчас, это то, что вы заменяете фрагмент с этим кодом

getSupportFragmentManager()
        .beginTransaction()
        .replace(R.id.container_fragment, fragment, tag)
        .commit();

, в то время как вы можете добавить фрагмент вместо того, чтобы заменять их следующим образом:

getSupportFragmentManager()
        .beginTransaction()
        .add(R.id.container_fragment, fragment, tag)
        .commit();

что это будетсделать это будет добавить фрагмент вместо того, чтобы заменить его, так что состояние фрагмента будет сохранено.

0 голосов
/ 01 ноября 2019

Попытайтесь переместить действия извлечения первых 3 фрагментов в методе onCreate.

Причина этого заключается в том, что при повторном вводе фрагмента ваш onActivityCreated вызывается и снова получает данные, а затем обновляет программу повторного просмотра, которая сбрасываети вернитесь к началу просмотра повторного просмотра.

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

...