我有一个活动,它从支持库托管DrawerLayout和NavigationView。我将标题布局设置为导航视图,我希望导航标题高度为" wrap_content"。所以当我将高度设置为" wrap_content"标题布局位于状态栏后面。
我想要的结果是导航抽屉应该在状态栏后面绘制,但导航标题应该按状态栏高度向下推。
下面是我得到的截图。注意"登录"按钮位于状态栏后面。
活动布局
<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>
导航视图标题布局
<?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>
我已经通过StackOverflow搜索了一个解决方案,但无法找到它。所以有人请说清楚。提前谢谢。
答案 0 :(得分:9)
<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"/>
android:fitsSystemWindows =“false”
和CoordinatorLayout =&gt;机器人:fitsSystemWindows = “假”
答案 1 :(得分:3)
首先,请记住,您不能在棒棒糖之前绘制状态栏。
对于Lollipop +,您应该将android:fitsSystemWindows="true"
设置为DrawerLayout
,而将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()
}
}
窗口正在将名为insets
的对象(其尺寸分别为顶部,左侧,底部,右侧)传递到其子视图。带有fitSystemWindows=true
的子视图将对此插图无效,并且可以将其发送给子视图。值为false的视图可以使用这些值为其自身添加额外的填充或边距。
fitSystemWindows=false
中的NavigationView
的设置不起作用,因为它正在使用插图对其自身施加额外的余量。您想要的是标题视图LinearLayout
,以应用此边距。但是NavigationView
中有两个中间容器视图,它们不会将插图传递到LinearLayout
,因此您必须在这些容器之前拦截窗口插图,并自己应用标题视图的边距或填充
无论Android版本是什么,都不要假设窗口插入量将是固定值或从资源中获取它们。特定的设备具有特定的窗口插入值,有些具有较大的“缺口”以适合大型相机,有些制造商决定使其厚度小于Android建议的规格。
答案 2 :(得分:-1)
您使用COL2
作为标题布局的根元素。 LinearLayout
,FrameLayout
等是忽略LinearLayout
属性的基本布局。 我建议您使用android:fitsSystemWindows
作为标题布局的根元素。将CoordinatorLayout
属性设置为CoordinatorLayout
的{{1}}会自动调整其内部填充以防止其子元素被系统窗口(例如状态栏)重叠。
这些信息来自this article,“我为什么要适合SystemWindows?”伊恩湖(Ean Lake)
尽管基本布局(FrameLayout,LinearLayout等)使用默认行为,但是有许多布局已经自定义了它们对fitsSystemWindows的反应以适应特定用例。
...
CoordinatorLayout还利用了它处理窗口嵌入的方式,允许子视图上的Behavior设置在每个子视图本身调用dispatchApplyWindowInsets()之前,拦截并更改View对窗口嵌入的反应。它还使用fitsSystemWindows标志来了解是否需要绘制状态栏背景。
要实现所需的功能,请确保遵循以下布局结构。
布局/activity_xxxxx.xml
android:fitsSystemWindows
layout / nav_header.xml
true