【问题标题】:Android Jetpack Navigation How to handle the Toolbar and BottomNavBar contentAndroid Jetpack Navigation 如何处理 Toolbar 和 BottomNavBar 内容
【发布时间】:2019-07-24 20:34:44
【问题描述】:

我对导航组件如何适应应用程序行为感到有些困惑。在教程中,这一切看起来都很好,很闪亮,您不会做太复杂的事情,但在实际应用中实现时,情况似乎有所不同。

导航前

在实现导航之前,我必须手动运行片段事务。为此,我的片段将实现一个接口onFragmentAction,它将bundle 传递给主Activity,并在基于动作的活动中,用另一个片段替换当前片段。

需要处理的第二部分是顶部工具栏和BottomAppBar。例如BottomAppBar 需要使FAB 在某些片段上以不同方式对齐或隐藏在其他片段中。此外,顶部ToolBar 需要在某些上展开或在其他上折叠。为此,我听了FragmentManager.OnBackStackChangedListener 并根据片段标签getSupportFragmentManager().getBackStackEntryAt(size - 1).getName() 相应地更改布局。

带导航

第一部分似乎很容易做到:传递参数并开始新的片段。但我不知道导航是否可以处理工具栏管理,或者我需要继续从我的活动中管理它。

【问题讨论】:

    标签: android android-architecture-components android-jetpack android-architecture-navigation


    【解决方案1】:

    尽管 Alex 的解决方案有效,但我不建议将其用于管理工具栏。

    工具栏应该是片段布局的一部分,每个片段都应该管理自己的工具栏。您可以为每个片段膨胀不同的菜单。即使想要在活动中使用工具栏,我也建议获取对工具栏表单活动的引用(通过界面),然后在片段本身中添加和操作其项目。

    这将使您的活动和片段分离(这是拥有导航图和路由器的目标之一)。一个好的经验法则是,假设您想删除片段,那么您不需要对活动进行任何更改。

    【讨论】:

    • 有趣的地方。但是,如果活动托管工具栏并且我从片段中操作它,活动是否不需要处理单击的菜单项?所以在这种情况下,我仍然需要更新活动。
    • 如果你有工具栏的引用,你可以直接在片段中工具栏的项目上注册监听器。我过去已经完成了所有这些组合,问题最少的是处理片段中有关工具栏的所有内容,这是工具栏只是一个视图而不是活动组件的主要原因之一。特别是如果您可能想更改某些片段而不是其他片段中的应用栏行为(比如使用扩展的应用栏或使用快速返回方法)
    • 我认为这取决于,如果我想要一个漂亮的动画,工具栏汉堡包转换为后退箭头,我建议在活动中使用工具栏和它下面的片段。在这种情况下,您可以将工具栏视为一个导航概念,它应该只由控制视图的事物控制,即执行片段事务的活动。但是,如果您将自定义内容添加到工具栏中,则将其放入片段中会很有意义,因为它更多地是对片段的控制,而不是仅对视图之间的导航。
    • 使用这种方法,具有相同工具栏的每个片段都会重新实现相同的功能,因此该解决方案无法随着应用程序的增长而很好地扩展
    • 你有实现这个的示例项目吗? :)
    【解决方案2】:

    工具栏标题是根据导航图中的'label'值设置的,如果你想用工具栏或BottomAppBar做一些不同的事情,你可以在你的活动中添加addOnNavigatedListener,并根据当前的目的地做一些事情。

    findNavController(nav_host_fragment).addOnNavigatedListener { controller, 
     destination ->
     when(destination.id) {
        R.id.destination1 -> {
            //Do something with your toolbar or BottomAppBar
        }
        R.id.destination2 -> {
            //Do something with your toolbar or BottomAppBar
        }
    
     }
    }
    

    【讨论】:

    • 在实现'androidx.navigation:navigation-fragment:2.3.1'中没有addOnNavigatedListener接口
    【解决方案3】:

    在您的片段中:

    NavController navHostFragment = NavHostFragment.findNavController(this);
    NavigationUI.setupWithNavController(toolbar, navHostFragment);
    

    当我单击列表项 (Explore Fragment) 上的项目时,它将否定 DetailFragment,当我单击工具栏上的后退按钮时,它将返回 MainFragment

    【讨论】:

    • 我在哪里写这段代码?仅在探索片段中?
    • 我认为你应该在 MainActivity 写这个,其中包含那个片段
    【解决方案4】:

    如果你想通过调用菜单项到达另一个片段,你必须给项目 id 赋予与目标 id 相同的 id。

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return 
           item.onNavDestinationSelected(findNavController(R.id.nav_host_fragment))
                || super.onOptionsItemSelected(item)
    }
    
    
    <item android:id="@+id/dailyInfoFragment"
          android:title="@string/action_settings"
          android:orderInCategory="100"
          app:showAsAction="never"/>
    
    
        <fragment
            android:id="@+id/dailyInfoFragment"
            android:name="com.example.sonyadmin.infoPerDay.DailyInfoFragment"
            android:label="fragment_daily_info"
            tools:layout="@layout/fragment_daily_info"
            />
    

    【讨论】:

      猜你喜欢
      • 2021-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多