Поведение нижней панели навигации приложения Google Фото - PullRequest
2 голосов
/ 07 мая 2020

Долгое время я исследовал, как сохранять состояния между фрагментами, поэтому, когда я возвращаюсь, это как будто вы никогда не уходили. Google Фото - ключевой пример. Когда вы пролистываете свои фотографии, а затем go к другому фрагменту и возвращаетесь, вы остаетесь там, где были. У меня вопрос, как этого достичь, поскольку мое приложение загружает разные фрагменты, и когда они возвращаются к ним, они воссоздаются вместо загрузки своего предыдущего состояния, как это происходит с Google Фото. Что я пробовал:

Часть кода, в которой определяется nav_host_fragment , поскольку это navView

 appBarConfiguration = new AppBarConfiguration.Builder(
        R.id.navigation_home, R.id.navigation_profile, R.id.navigation_locate, R.id.navigation_contact_messages, R.id.navigation_settings)
        .build();

    navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    //NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
    NavigationUI.setupWithNavController(navView, navController);

    navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    //NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
    NavigationUI.setupWithNavController(navView, navController);

    navView.setOnNavigationItemReselectedListener(menuItem -> {

    });

    navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
        if (destination.getLabel() != null) {
            if (levelsFragment[0].equals(destination.getLabel().toString())) {
                //reemplazar por accion
            } else if (levelsFragment[1].equals(destination.getLabel().toString())) {
                //reemplazar por accion
            } else if (levelsFragment[2].equals(destination.getLabel().toString())) {
                //reemplazar por accion
            } else if (levelsFragment[3].equals(destination.getLabel().toString())) {
                //reemplazar por accion
            } else if (levelsFragment[4].equals(destination.getLabel().toString())) {
                //reemplazar por accion
            }
        }
    });

Xml MainActivity, содержащего bottomNavigation :

<androidx.constraintlayout.widget.ConstraintLayout 
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_wrapper"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/nav_view"
    style="@style/bottomNav"
    android:layout_width="0dp"
    app:itemTextColor="@color/quantum_grey"
    android:animateLayoutChanges="true"
    app:labelVisibilityMode="auto"
    app:itemIconTint="@color/colorAccent"
    android:layout_height="wrap_content"
    android:layout_marginStart="0dp"
    android:layout_marginEnd="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:menu="@menu/bottom_nav_menu" />

<fragment
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="?actionBarSize"
    app:defaultNavHost="true"
    app:layout_constraintBottom_toTopOf="@id/nav_view"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:navGraph="@navigation/mobile_navigation" />


</androidx.constraintlayout.widget.ConstraintLayout>

Например, в itemReselected я оставил его пустым, потому что каждый раз, когда я просматриваю его, он создавал для меня новый экземпляр. AddOnDestinationChangedListener решил, что именно здесь происходит сохранение состояния. Любая помощь будет оценена. Вот страница, на которой прекрасно объясняется, чего я хочу достичь: Material.io

Нижняя навигация ведет себя по-разному в Android и iOS. Когда вы выбираете нижний элемент навигации (тот, который в настоящее время не выбран), каждая платформа отображает разные результаты:

  • Вкл. Android: приложение переходит на экран верхнего уровня пункта назначения. Все предыдущие действия пользователя и временные состояния экрана сбрасываются, например, положение прокрутки, выбор вкладки и встроенный поиск.
  • Вкл. iOS: место назначения отражает предыдущее взаимодействие пользователя. Если пользователь ранее посещал этот раздел приложения, он возвращается к последнему просмотренному экрану (с сохранением предыдущего состояния, если это возможно). В противном случае приложение переходит на экран верхнего уровня.

Навигация по платформе по умолчанию может быть переопределена, когда это необходимо для улучшения взаимодействия с пользователем. Например, приложение Android, которое требует частого переключения между разделами, может сохранять состояние каждого раздела. Или приложение iOS может возвращать пользователей на экран верхнего уровня (или сбрасывать их положение прокрутки), если это лучше подходит для варианта использования.

Это письмо от Google Issue Tracker. Где мое беспокойство четко выражено и что в Google Фото все сделано правильно. НЕОБХОДИМО РЕШЕНИЕ ПРОБЛЕМЫ

Две самые большие проблемы и неудобства, связанные с этой ошибкой для наших конечных пользователей с новой библиотекой навигации и нижней частью Панель навигации:

  • Смена вкладки с нижней панелью сбрасывает состояние и задний стек предыдущей вкладки / фрагмента, поэтому наши пользователи полностью теряют свою историю навигации (это правильно реализовано в приложении Google Фото)
  • При обратном нажатии с root одной вкладки вместо выхода из приложения отображается исходная вкладка / фрагмент "

Я нашел это, выполнив поиск в inte rnet, но он находится в kotlin, и есть вещи, которые я не очень хорошо понимаю, и я не знаю, именно это мне нужно: Код в GitHub

1 Ответ

0 голосов
/ 25 мая 2020

Я не знаю, есть ли более чистый способ сделать это, но, возможно, вы можете попытаться сохранить важные вещи, чтобы воссоздать представление (например, положение прокрутки и, возможно, встроенный поиск), а затем автоматически прокрутите до старой позиции при повторном открытии . Также можно сохранить старый экземпляр (с данными прокрутки, если они существуют), а затем, когда вы переключаетесь обратно, вы копируете старую версию обратно вместо создания новой. Будьте осторожны, чтобы скопировать объект old-screen-object, а не устанавливать ссылку, потому что он, очевидно, удаляется при создании следующего объекта ..

...