使用单独的 backstack 创建类似底部导航的 Instagram
Posted
技术标签:
【中文标题】使用单独的 backstack 创建类似底部导航的 Instagram【英文标题】:Create Instagram like bottom navigation with separate backstack 【发布时间】:2021-10-09 14:00:42 【问题描述】:我是 android 开发新手,需要一些指导。我正在尝试实现 Instagram 底部导航等功能。让我描述一下我所说的功能是什么意思。
所需的功能
底部导航应该在大多数屏幕上持续显示(不包括少数,即 AddPostScreen)
我有 this bottom navigation 与 Home、Discover、AddPost、Market 和 Profile。点击每个选项应该会带来相关的屏幕。 (我知道这是非常基本的底部导航功能,我在这里提到它是为了更好地理解下一点)
打开一个新屏幕将在原始屏幕之上打开。例如,如果我在个人资料屏幕并打开关注者的屏幕,它应该在个人资料的顶部打开,以便关闭关注者的屏幕应该带来个人资料。从追随者屏幕,也可以像这样打开其他屏幕。如果我按此顺序打开屏幕: 个人资料->关注者->A->B 然后关闭(从屏幕上的后退按钮和手机的android后退按钮)B将带来A,关闭A应该带来关注者,依此类推。
第二次点击底部导航选项应该会带来原始屏幕并关闭其顶部的所有屏幕。在上面的示例中,如果用户点击配置文件,其他屏幕(关注者、A、B)应该关闭。配置文件屏幕应显示相同的状态。
对于每个选项(底部导航),可以在原始屏幕之上打开多个屏幕。像这样 Home-> A-> B->C & Profile-> D-> E->F 并且用户应该能够在它们之间来回切换。让我解释一下,如果我在家并打开 A 屏,然后转到 Profile 并打开 D 屏。现在我可以在打开 A 屏的情况下返回主页。我还可以在 A 屏上打开 B 屏。现在,如果我按下返回,只有 Home 的屏幕应该关闭,而 Profile 的屏幕不应该受到影响。
现在功能已经很清楚了,我将分享我已经为实现所需功能所做的工作。
我已经做了什么
我创建了一个带有(我自己的自定义)底部导航和 ViewPager2 的 MainActivity。底部导航将持续显示在所有屏幕上。 我为 Home、Discover、Market 和 Profile 创建了 Fragments。并使用了FragmentStateAdapter和ViewPager2来显示原来的四个片段。只有四个片段,因为 AddPost(底部导航的中心选项)会打开一个新活动。 在每个片段中,我放置了一个片段容器以在原始片段之上打开新片段。如果要从主屏幕-A 打开,我可以通过创建屏幕-A 片段并将其替换在主片段的片段容器上来实现。我可以从那里打开 screen-B 片段,它将再次替换 Home 片段的片段容器。在处理同一个片段容器时,我可以轻松替换片段和弹出片段。我可以使用这种技术实现前四个所需的功能。但是在实现最后一个功能时会变得更加棘手。对于最后一个功能,我认为我应该为每个片段容器设置一个单独的后台堆栈,但事实并非如此。我只有一个后台堆栈来管理来自所有片段容器的所有片段。我试图创建自己的后台堆栈,但我不明白该怎么做。 我已经描述了我想要什么以及我已经尝试过什么。如果有人有任何想法,请指导我。如果 Instagram 正在这样做,那么一定有办法做到这一点。
【问题讨论】:
【参考方案1】:当您将片段 A 移动到片段 B 时,兄弟首先了解片段行为,因此在这种情况下,片段 A 视图销毁但片段 A 在后堆栈上,因此这意味着当您返回片段 A 时,视图重新膨胀而不是重新创建片段.
下面的代码管理你的后台堆栈 bottom_navigation.setOnNavigationItemSelectedListener(BottomNavigationView.OnNavigationItemSelectedListener item -> if (navController.currentDestination != null) 如果(item.itemId == R.id.homeFragment) if (navController.currentDestination!!.label != "homeFragment") navController.popBackStack(R.id.homeFragment, false) else if (item.itemId == R.id.auctionFragment) if (navController.currentDestination!!.label != "AuctionFragment") if (!navController.popBackStack(R.id.auctionFragment, false)) navController.navigate(R.id.auctionFragment) else if (item.itemId == R.id.chatsFragment) if (navController.currentDestination!!.label != "ChatsFragment") if (!navController.popBackStack(R.id.chatsFragment, false)) navController.navigate(R.id.chatsFragment) else if (item.itemId == R.id.profileFragment) if (navController.currentDestination!!.label != "ProfileFragment") if (!navController.popBackStack(R.id.profileFragment, false)) navController.navigate(R.id.profileFragment) else if (item.itemId == R.id.CategoryFragment) if (navController.currentDestination!!.label != "AddFragment") if (!navController.popBackStack(R.id.CategoryFragment, false)) navController.navigate(R.id.CategoryFragment) 真的 )
【讨论】:
以上是关于使用单独的 backstack 创建类似底部导航的 Instagram的主要内容,如果未能解决你的问题,请参考以下文章
Backstack management : Restarter 只能在所有者初始化阶段创建
当backstack为空时,按下android上的后退按钮会破坏导航逻辑