在Android中将状态栏填充设置为NavigationView

Sre*_*nth 13 android navigation-drawer material-design navigationview androiddesignsupport

我有一个活动,它从支持库托管DrawerLayout和NavigationView.我正在为导航视图设置标题布局,我希望导航标题高度为"wrap_content".因此,当我将高度设置为"wrap_content"时,标题布局会位于状态栏后面.

我想要的结果是导航抽屉应该在状态栏后面绘制,但导航标题应该按状态栏高度向下推.

下面是我得到的截图.请注意状态栏后面的"SIGN IN"按钮.

截图

活动布局

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/nav_drawer"
android:fitsSystemWindows="true">

<android.support.design.widget.CoordinatorLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"></android.support.v4.view.ViewPager>
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <include layout="@layout/include_toolbar"/>

        <android.support.design.widget.TabLayout
            app:theme="@style/ThemeOverlay.AppCompat.Dark"
            style="@style/MyCustomTabLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/tabs"
            />

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

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

<android.support.design.widget.NavigationView
    android:id="@+id/navigation_view"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    app:headerLayout="@layout/nav_header"
    app:menu="@menu/menu_navigation"
    android:fitsSystemWindows="true"
    android:layout_gravity="start"/>

</android.support.v4.widget.DrawerLayout>
Run Code Online (Sandbox Code Playgroud)

导航视图标题布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:background="?attr/colorPrimaryDark"
          android:padding="16dp"
          android:theme="@style/ThemeOverlay.AppCompat.Dark"
          android:orientation="vertical"
          android:fitsSystemWindows="true"
          android:gravity="bottom">

<TextView
    android:visibility="gone"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/text_user_name"
    android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>

<TextView
    android:visibility="gone"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/text_email"
    android:textAppearance="@style/TextAppearance.AppCompat.Body2"/>

<Button
    android:id="@+id/button_sign_in"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Sign In"/>

</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

我通过StackOverflow搜索了一个解决方案,但找不到它.所以有人请说清楚.提前致谢.

Pan*_*ian 11

<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
app:headerLayout="@layout/nav_header"
app:menu="@menu/menu_navigation"
android:fitsSystemWindows="false"
android:layout_gravity="start"/>
Run Code Online (Sandbox Code Playgroud)

机器人:fitsSystemWindows = "假"

和CoordinatorLayout => android:fitsSystemWindows ="false"

  • 这将导致抽屉被绘制在状态栏下方,这不是所需的行为. (11认同)

All*_*oso 6

首先,请记住您不能在 Lollipop 之前在状态栏后面绘制。

解决方案

对于 Lollipop+,您应该设置android:fitsSystemWindows="true"forDrawerLayout并保留默认值NavigationView

然后在设置标题后在您的活动或片段上:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
    navigationView.setOnApplyWindowInsetsListener { v, insets ->

        val header = navigationView.getHeaderView(0)
        header.setPadding(
            header.paddingLeft, 
            header.paddingTop + insets.systemWindowInsetTop,
            header.paddingRight, 
            header.paddingBottom
        )
        insets.consumeSystemWindowInsets()
    }
}
Run Code Online (Sandbox Code Playgroud)

解释

该窗口正在将一个名为insets(具有顶部、左侧、底部、右侧的尺寸)的对象传递给它的子视图。具有fitSystemWindows=truewill的子视图不对此插入做任何事情,并且可以将其转发给其子视图。设置为 false 的视图可能会使用这些值为其自身添加额外的填充或边距。

设置fitSystemWindows=falseNavigationView,因为它使用的是插图额外保证金适用于本身不工作。你想要的是你的标题视图LinearLayout来应用这个边距。但是内部有两个中间容器视图NavigationView不会将插图传递给您的LinearLayout,因此您必须在这些容器之前拦截窗口插图并应用自己的页眉视图的边距或填充。

你永远不应该做的事

永远不要假设窗口插入将是一个固定值或从资源中获取它们,无论 Android 版本是什么。特定设备具有特定的窗口插入值,有些具有更厚的“凹口”以适合大型相机,有些制造商决定使其比 Android 推荐的规格更薄。