工具栏下方的导航抽屉

Posted

技术标签:

【中文标题】工具栏下方的导航抽屉【英文标题】:Navigation Drawer Below Toolbar 【发布时间】:2015-01-15 02:34:45 【问题描述】:

我正在尝试让导航抽屉在工具栏下方打开。

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:id="@+id/drawer_layout"
tools:context=".MainActivity">
<RelativeLayout
    android:layout_width = "match_parent"
    android:layout_height = "wrap_content">
    <include layout="@layout/toolbar"
        android:id="@+id/toolbar"/>
    <FrameLayout
        android:layout_below="@+id/toolbar"
        android:layout_
        android:layout_
        android:background="@color/background_color"/>
</RelativeLayout>
<ListView
    android:id="@+id/drawer"
    android:layout_
    android:layout_
    android:layout_below="@+id/toolbar"
    android:layout_marginTop="56dp"
    android:layout_gravity="start">
</ListView>
</android.support.v4.widget.DrawerLayout>

如何重新格式化 xml,以便在工具栏下方打开导航栏?

【问题讨论】:

@tyczj 如果您查看最新版本的 Google Play 商店。导航抽屉位于工具栏下方。我想实现类似的东西。 @tyczj 导航栏打开时如何处理工具栏操作 你没有,如果你有想要用户在抽屉打开时执行的操作,那么你应该把它们放在抽屉布局中 How do I make DrawerLayout to display below the Toolbar?的可能重复 【参考方案1】:

您应该将DrawerLayout 移出最高父级,并将Toolbar 移出DrawerLayout 内容容器。 简而言之,这看起来像:

RelativeLayout
 ----Toolbar
 ----DrawerLayout
     ---ContentView
     ---DrawerList 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/top_parent"
    android:layout_
    android:layout_
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <include
        android:id="@+id/toolbar"
        layout="@layout/toolbar" />

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_
        android:layout_
        android:layout_below="@+id/toolbar">

        <FrameLayout
            android:id="@+id/content_frame"
            android:layout_
            android:layout_
            android:background="@color/background_color" />

        <ListView
            android:id="@+id/drawer"
            android:layout_
            android:layout_
            android:layout_below="@+id/toolbar"
            android:layout_gravity="start"
            android:layout_marginTop="56dp" />

    </android.support.v4.widget.DrawerLayout>
</RelativeLayout>

但是,Material Design 指南规定 Navigation Drawer 应位于 Toolbar 上方。

【讨论】:

这将允许我在抽屉打开的情况下处理工具栏操作? 是的。因为抽屉只会响应 Rect 的事件,所以它是有界的。 但状态栏现在与工具栏重叠。如何解决这个问题? fitsystemwindows 设置为 true 会导致该问题。反正解决了。 优秀的答案尼古拉!只是一点改进。对于 ListView 使用 android:layout_marginTop="?attr/actionBarSize" 并在工具栏中设置与高度相同的值。【参考方案2】:

你应该简单地添加

android:layout_marginTop="@dimen/abc_action_bar_default_height_material"

到您用作抽屉的布局。

这将自动调整工具栏下方的导航抽屉,并且还支持不同的屏幕尺寸。

【讨论】:

不幸的是,@dimen/abc_action_bar_default_height_material 在兼容性库中被标记为私有,因此该解决方案使用起来不安全,因为资源名称可能会在库的未来版本中消失。 滑出时工具栏上仍然会产生阴影。那不是想要的效果。不是最好的方法。【参考方案3】:

你可以像这样添加layout_marginTop

<android.support.design.widget.NavigationView
        android:layout_marginTop="@dimen/abc_action_bar_default_height_material"
        android:id="@+id/nav_view"
        android:layout_
        android:layout_
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />

但抽屉将显示为工具栏的顶层。


这是另一种将其添加到工具栏下方的 Choppy 方式!!!

可能不是最好的,但它有效!

最终结果会是这样的

如果您将项目创建为 Navigation Drawer 项目 (Navigation Drawer Activity),它将在您的 layout 文件夹中创建四个 XML 文件

app_bar_main content_main navigatin_main

activity_main

这些 xml 是如何链接的? 我看到大多是 include tag 被使用

您的 Activity 与 activity_main 相关联

activity_mainapp_bar_mainnavigation_view(抽屉) app_bar_main 默认有 toolbarcontent_main

现在让我们移除 activity_main 并将其内容直接设置为 app bar main 并将其用作 Activity 的主布局。

在工具栏下添加抽屉 将它添加到android.support.design.widget.AppBarLayout 下,因为它包含工具栏并且它应该在顶部。

这里是 app_bar_main.XML 的示例

      <?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:layout_
    android:layout_
    android:fitsSystemWindows="true"
    tools:context="none.navhead.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_
        android:layout_
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_
            android:layout_
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>



    //------ taken from activity_main
    // content main
    <include layout="@layout/content_main" />

    // you need this padding
    <android.support.v4.widget.DrawerLayout
        android:paddingTop="?attr/actionBarSize"
        android:id="@+id/drawer_layout"
        android:layout_
        android:layout_
        tools:openDrawer="start">

        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_
            android:layout_
            android:layout_gravity="start"
            android:fitsSystemWindows="true"
            app:headerLayout="@layout/nav_header_main"
            app:menu="@menu/activity_main_drawer" />

    </android.support.v4.widget.DrawerLayout>


</android.support.design.widget.CoordinatorLayout>

p.s 您可以将 app_bar_main.XML 设置为您的活动的 setContentView 随便玩,有很多方法;)

【讨论】:

这对我也适用于 API23,其中 NavigationView 被设计为绘制在系统状态栏后面。但是,它仍然在顶部绘制了阴影,就好像它仍然绘制在状态栏后面一样,所以我必须将 app:insetForeground="@null" 添加到 NavigationView,并且它正确绘制在操作栏(或实际上是工具栏)下方。这样,左上角的动画箭头也是可见的,没有被 NavigationView 覆盖。 我还需要将android:layout_marginTop="?attr/actionBarSize" 添加到DrawerLayout,以使内容和导航正确可见。 当我使用它时,片段中的数据是不可点击的。请问怎么解决 @roshan posakya 你把你的片段放在哪里了? @Charuka 感谢回复,但我用不同的方式解决了这个问题..【参考方案4】:

这是我的布局和完美的工作: 活动主:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:layout_
    android:layout_>
    <!-- AppBarLayout should be here -->
    <android.support.design.widget.AppBarLayout
        android:layout_
        android:layout_
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_
            android:layout_
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    </android.support.design.widget.AppBarLayout>

    <!-- add app:layout_behavior="@string/appbar_scrolling_view_behavior" -->

    <android.support.v4.widget.DrawerLayout
        android:id="@+id/drawer_layout"
        android:layout_
        android:layout_
        android:fitsSystemWindows="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:openDrawer="start">

        <include
            layout="@layout/app_bar_main"
            android:layout_
            android:layout_ />

        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_
            android:layout_
            android:layout_gravity="start"
            android:fitsSystemWindows="true"
            app:headerLayout="@layout/nav_header_main"
            app:menu="@menu/activity_main_drawer" />
    </android.support.v4.widget.DrawerLayout>
</android.support.design.widget.CoordinatorLayout>

app_bar_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
  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:layout_
  android:layout_
  android:fitsSystemWindows="true"
  tools:context=".activty.MainActivity">
<include layout="@layout/content_main"/>
</FrameLayout>

结果: 波纹管工具栏

【讨论】:

这个用于将它放在带有折叠图像的折叠工具栏下。它停留在图像下方。 完美。它应该适用于所有人。【参考方案5】:

如果您使用的是自定义工具栏,请以这种方式使用抽屉布局..

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_
android:layout_
android:orientation="vertical">

    <!-- The toolbar -->
    <android.support.v7.widget.Toolbar  
        android:id="@+id/my_awesome_toolbar"
        android:layout_
        android:layout_
        android:minHeight="?attr/actionBarSize"
        android:background="?attr/colorPrimary" />

    <android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/my_drawer_layout"
    android:layout_
    android:layout_>

        <!-- drawer view -->
        <LinearLayout
            android:layout_
            android:layout_
            android:layout_gravity="left|start">
            ....
        </LinearLayout>

    </android.support.v4.widget.DrawerLayout>

</LinearLayout>

如果您不使用自定义工具栏,则必须将边距设置为抽屉布局..

android:layout_marginTop ="?android:attr/actionBarSize"

【讨论】:

【参考方案6】:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 
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/drawer_layout"
    android:layout_
    android:layout_
    android:fitsSystemWindows="false"
    tools:openDrawer="start">
    <include
        layout="@layout/app_bar_main"
        android:layout_
        android:layout_ />
    <android.support.design.widget.NavigationView
        android:layout_marginTop="?attr/actionBarSize"
        android:id="@+id/nav_view"
        android:layout_
        android:layout_
        android:layout_gravity="start"
        android:fitsSystemWindows="false"
        app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>

【讨论】:

android:fitsSystemWindows="false"【参考方案7】:

设置了一个简单而良好的解决方案 fitsSystemWindows=false
android.support.v4.widget.DrawerLayout

id 为

android:id="@+id/drawer_layout"

对于navigationView,将layout_marginTop 设置为?attr/actionBarSize,这将获取操作栏大小并将其设置为边距

Here is complete code 的 activity_main.xml 具有上述两个更改。

【讨论】:

以上是关于工具栏下方的导航抽屉的主要内容,如果未能解决你的问题,请参考以下文章

Vuetify 2 个工具栏和 1 个导航抽屉,导航抽屉上方有 1 个工具栏

导航抽屉和工具栏出现在初始屏幕中

导航抽屉没有覆盖我的工具栏[重复]

使用带有喷气背包导航组件的导航抽屉时如何更改工具栏图标(汉堡图标)

片段和导航抽屉的不同工具栏

工具栏和导航抽屉