Google 相册应用底部导航栏行为

Posted

技术标签:

【中文标题】Google 相册应用底部导航栏行为【英文标题】:Google Photos app bottom navigation bar behavior 【发布时间】:2020-08-22 08:20:47 【问题描述】:

很长一段时间以来,我一直在研究如何保存片段之间的状态,所以当我返回时,就好像你从未离开过一样。谷歌照片就是一个重要的例子。当您滚动浏览照片然后转到另一个片段并返回时,您会保持原样。我的问题是如何实现这一点,因为我的应用程序加载了不同的片段,当它们返回到这些片段时,它们被重新创建,而不是像谷歌照片那样加载它们以前的状态。我尝试过的:


定义 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_
android:layout_>

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/nav_view"
    style="@style/bottomNav"
    android:layout_
    app:itemTextColor="@color/quantum_grey"
    android:animateLayoutChanges="true"
    app:labelVisibilityMode="auto"
    app:itemIconTint="@color/colorAccent"
    android:layout_
    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_
    android:layout_
    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 问题跟踪器的电子邮件。我的担忧得到了明确表达,并且在谷歌照片中它是正确完成的。 必须有解决问题的办法

这个错误对我们的最终用户来说最大的两个问题和烦恼 新的导航库和底部导航栏是:

使用底部栏更改选项卡会重置前一个选项卡/片段的状态和后台堆栈,因此我们的用户完全失去了他们的导航历史记录(这在 Google 相册应用中已正确实现) 从一个选项卡的根目录按返回会显示初始选项卡/片段,而不是离开应用程序”

我通过搜索互联网找到了这个,但它在 kotlin 中,有些东西我不太了解,我不知道它是否正是我需要的:Code in GitHub

【问题讨论】:

对这个问题的回答更有价值 tnah 50 分,但我还不够抱歉 虽然,有很多答案here 可用于保存 Fragment 的状态或不破坏它,因此在再次选择时不会重新加载,但我相信 this 对你有帮助最多。 但是,请记住,如果您的片段要保持打开状态,您需要管理您真正需要的内存资源,因为高内存消耗会使您的应用程序被系统内存管理器杀死,然后片段将重新加载。 【参考方案1】:

我不知道是否有更简洁的方法来做到这一点,但也许你可以尝试保存重要的东西来重新创建视图(比如滚动位置和内联搜索),然后在重新打开时自动滚动到旧位置. 也可以保存旧实例(带有滚动数据,如果存在的话),然后当您切换回来时,您将旧版本复制回来而不是生成新版本。小心复制旧屏幕对象而不是设置引用,因为它显然会在生成下一个对象时被删除..

【讨论】:

感谢您的回答,但如果您在问题中看到,材料设计表示该行为可以被覆盖,我想知道如何做到这一点

以上是关于Google 相册应用底部导航栏行为的主要内容,如果未能解决你的问题,请参考以下文章

在android中更改底部导航栏的项目

Android学习之BottomNavigationBar实现Android特色底部导航栏

使用底部导航栏导航回页面时颤动通过底部导航栏选择的索引

使用底部应用栏标签导航 - 颤动

jumbotron的引导导航栏底部向右偏移

Android ------ Android X 的BottomNavigationView底部导航栏