【问题标题】:Navigation Architecture Component - Detail View with CollapsingToolbar导航架构组件 - 带有 CollapsingToolbar 的详细视图
【发布时间】:2018-10-23 12:41:39
【问题描述】:

新导航组件的提议实践在 I/O 上展示了以下模板和提议的理念:

  1. 一个应用程序的一个活动
  2. Activity 包含工具栏和底部导航栏

一个典型的应用程序通常有一个带有 CollapsingToolbar 的详细视图。在那种架构下如何构建它?

  • 将工具栏移动到每个片段 XML?
  • 以编程方式实现折叠工具栏?
  • 将详细信息片段移动到其自己的活动中(无论如何它可能会使用自己的深层链接)并“打破”理念?

【问题讨论】:

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


    【解决方案1】:

    一个典型的应用程序通常有一个带有 CollapsingToolbar 的详细视图。在那种架构下如何构建它?

    好问题!我也为此苦苦挣扎了一下,得出的结论是应该有一个带有 NavHostFragment 的 Activity,理想情况下,没有别的。这为您提供了最大的灵活性来显示(或不显示)每个屏幕所需的任何内容。重要的是,请确保您的主题删除了 ActionBar:

    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    

    这会引出你的下一个问题...

    将工具栏移动到每个片段 XML?

    在我看来,是的!您通常使用 ActionBar 的一切都可以通过工具栏完成。这是一个快速的 sn-p,它展示了如何使用 Toolbar 来执行您过去使用 ActionBar 的最重要的事情(向上导航、标题、选项菜单等...):

    toolbar.apply {
        setNavigationOnClickListener { findNavController().navigateUp() }
        setTitle(R.string.toolbar_title)
        inflateMenu(R.menu.fragment_menu)
        setOnMenuItemClickListener(::onMenuItemClick)
    }
    

    以编程方式实现折叠工具栏?

    这取决于您到底想做什么,但很可能没有必要这样做。您可以将 AppBarLayout、CollapsingToolbarLayout 和 Toolbar 拖放到您的布局中并像平常一样使用它们。给你的 AppBarLayout 一个 ActionBar 主题覆盖。这是一个例子:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/coordinatorLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appBarLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar">
    
            <com.google.android.material.appbar.CollapsingToolbarLayout
                android:id="@+id/collapsingToolbarLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:contentScrim="@color/primary"
                app:layout_scrollFlags="scroll|exitUntilCollapsed">
    
                <androidx.appcompat.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:layout_collapseMode="pin"
                    app:navigationIcon="@drawable/ic_up_white"/>
    
                ...
    

    将细节片段移动到它自己的活动中(它可能会使用自己的深层链接)并“打破”理念?

    上面不需要那个,对吧?这种方法足够灵活,可以在一个导航图中轻松容纳多个级别,并且仍然能够自定义图中每个目的地的外观和行为(包括类似于 ActionBar 的功能)。

    【讨论】:

    • 我添加了相同的,但是两个工具栏是可见的
    • @RahulDevanavar 您是否使用禁用了操作栏的主题?如果是这样,我会针对您的具体情况提出另一个问题,并确保包含主题 XML。
    【解决方案2】:

    试试

    appBarLayout = (AppBarLayout) findViewById(R.id.appbar);
    
    
    if(expandToolbar){
                    appBarLayout.setExpanded(true,true);
                }else{
                    appBarLayout.setExpanded(false,true);
                }
    

    这是一个常用的链接 disable expand on CollapsingToolbarLayout for certain fragments

    也适用于其他想要更改工具栏某些部分的人 您应该在单独的 XML 中编写自定义工具栏视图,并尝试在您的详细信息片段中以语法方式扩展自定义视图,然后隐藏未使用的元素 旧工具栏(如果有)。

    setSupportActionBar(toolbar);
    View logo = getLayoutInflater().inflate(R.layout.view_logo, null);
    toolbar.addView(logo);
    

    这里是你如何隐藏不需要的视图

    for (int i = 0; i < toolbar.getChildCount(); ++i) {
            View child = toolbar.getChildAt(i);
    
            // here u can hide all text views for example.
            if (child instanceof TextView) {
                child.setVisibility(View.GONE );
            }
        }
    

    这种方式比写两个activity好很多

    【讨论】:

      【解决方案3】:

      假设我们有

      1. 一个应用程序的一个活动
      2. Activity 包含工具栏和底部导航栏

      您的应用所需的工具栏的所有可能外观都应在该单个工具栏中实现,并且可以控制为当前活动的片段。 为了不违反依赖倒置原则,所有需要 Activity 工具栏中的功能的 Fragment 都必须实现一个接口。您可以使用 OnBackStackChangedListener 检查视图的更新

      getFragmentManager().addOnBackStackChangedListener(
          new FragmentManager.OnBackStackChangedListener() {
              @Override
              public void onBackStackChanged() {
                  Fragment visibleFragment = ...
                  if(visibleFragment instanceof ToolbarControlFragment) {
                      if(visibleFragment.shouldExpandToolbar()) {
                          // set AppBarLayout expanded state
                      }
                      // ...
                  }
              }
          }
      );
      

      当 Fragment 需要 OptionsMenu 时,您可能还记得这个原则。

      我通常建议在片段中只使用一个由活动控制的底部导航栏和几个工具栏。这降低了复杂性并使应用程序的组件更加独立。

      【讨论】:

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