在 Android N 多窗口模式下删除导航视图顶部填充
Posted
技术标签:
【中文标题】在 Android N 多窗口模式下删除导航视图顶部填充【英文标题】:Removing navigation view top padding in Android N Multi-Window mode 【发布时间】:2017-01-02 00:37:18 【问题描述】:我想在 android N 的多窗口模式下从导航视图中删除 paddingTop
/marginTop
。就像 Gmail 一样。
如果你看到下面的图片,我说的是正常的填充,大小等于导航视图开头的状态栏。
所以基本上在多窗口模式下(见下图),当我的应用位于屏幕的第二部分时,我必须删除该填充。
不幸的是,从新的 api 24 开始,您拥有 isInMultiWindowMode()
,但无法知道您的应用位于屏幕的哪个部分。
【问题讨论】:
【参考方案1】:您需要让导航视图标题尊重系统窗口插入,而不是试图弄清楚您是否处于多窗口模式以及屏幕的哪个部分。
通常你只关心一个窗口——你的应用程序被绘制的那个窗口。通常你甚至不认为有任何窗口。你的应用不是全屏绘制的吗?嗯,其实没有。通常会为系统栏保留一些空间,例如顶部的状态栏和底部的导航栏。它们被绘制在单独的窗口 - 系统窗口中。 (哦,现在我们在 N 中有了多窗口模式。更像是多应用程序窗口模式,因为如果你计算系统窗口,那么多窗口已经存在了一段时间。)
您可以让导航视图标题根据它是否在系统窗口下(在本例中为:状态栏)调整其插图,只需进行一些简单的调整。
假设导航视图是这样定义的:
<android.support.design.widget.NavigationView
...
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
... />
nav_header_main.xml
中有一个简单的标题布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="@drawable/nav_header_background"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="32dp">
<ImageView
android:id="@+id/imageView"
android:layout_
android:layout_
android:src="@android:drawable/default_profile_picture" />
...
</LinearLayout>
你只需要像这样改变它:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="@drawable/nav_header_background"
android:fitsSystemWindows="true"
android:orientation="vertical">
<ImageView
android:id="@+id/imageView"
android:layout_
android:layout_
android:src="@android:drawable/sym_def_app_icon"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"/>
...
</LinearLayout>
-
首先您需要将
android:fitsSystemWindows="true"
添加到布局中。
现在您需要将顶部填充变小,因为fitsSystemWindows
会自动添加填充状态栏的大小。因此,以前您的顶部填充来自标题的顶部,现在它仅来自状态栏的底部。
而且您必须将所有填充从布局中移到其他位置(例如,我将它们移动到子视图的边距),因为fitsSystemWindows
会覆盖这些填充。
在此之后,如果您的应用处于多窗口拆分的底部,则不会添加状态栏的填充。它还可以让您的导航视图在任何其他情况下看起来正常,如果它不在状态栏下方,或者状态栏在任何未来版本的 Android 或某些疯狂的自定义 ROM 中改变大小。
【讨论】:
我认为 NavigationView 中的 android:fitsSystemWindows="true" 就足够了。在标题布局中添加 android:fitsSystemWindows 也可以解决问题。谢谢 我刚刚发现这个解决方案只适用于 api 24+【参考方案2】:对我来说没有任何效果,所以我最终选择了这条路线并完成了工作:
<android.support.design.widget.NavigationView
...
app:insetForeground="@null"/>
从技术上讲,插图仍然存在,但由于用于绘制它们的 insetForeground
资源现在为空,因此 logic is skipped in ScrimInsetsFrameLayout's onDraw method(它是 NavigationView 的父类)。
所以当所有其他方法都失败时,这是一条相当有效的路线。
【讨论】:
以上是关于在 Android N 多窗口模式下删除导航视图顶部填充的主要内容,如果未能解决你的问题,请参考以下文章
在Android N多窗口模式下按下主页按钮时未调用Activity onStop()
Unity3D3D 视图操作 ( 视图基本元素 | 导航器 | 栅格 | 天空盒 | 3D 视图操作 | 视图旋转 | 视图缩放 | 视图平移 | 导航器操作 | 恢复方向 | 顶右前视图 )