安卓棒棒糖:ImageView忽略fitsSystemWindows属性(透明状态栏)

11

我目前正在开发一个应用程序,我想启用透明状态栏。我希望一个ImageView(我需要它的scaleType属性)覆盖整个屏幕,以便图像将显示在状态栏下方。这是我的布局:

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:fitsSystemWindows="true"
            android:scaleType="centerCrop"
            android:src="@drawable/picture" />

        <android.support.v7.widget.Toolbar
            (...toolbar stuff...)
        />

        (...some other stuff...)

    </RelativeLayout>

    <include layout="@layout/drawer" />
</android.support.v4.widget.DrawerLayout>

正如您所看到的,这是一个常规的DrawerLayout。请注意,DrawerLayoutRelativeLayoutImageView都将fitsSystemWindows属性设置为true。

我的问题是:如果我在上面的代码中对DrawerLayoutRelativeLayout中的任何一个设置背景资源(比如颜色或图片),我可以看到该颜色或图片“出现”在状态栏下方,完全符合我的要求。但是,ImageView的'src' drawable始终显示在其下方,就好像完全忽略了fitsSystemWindows属性一样。

我的主题中有以下属性:

<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/primary_dark</item>

由于primary_dark是半透明黑色(无论如何,这似乎不重要,因为正如我所说,这似乎是仅适用于我的ImageView的问题。透明状态栏对于DrawerLayoutRelativeLayout都可以完美工作。

5个回答

2

这对我来说完美地起作用。

在每个viewGroup参数中,您都有android:fitsSystemWindows="true"。尝试只在ImageView中保留一个。

或者完全删除它们。


1
fitSystemWindows

在RelativeLayout中不起作用。请使用FrameLayout或扩展FrameLayout的ViewGroup。


1

ImageView 扩展了 View,并没有覆盖它的方法 onApplyWindowInsets。 默认的逻辑定义在 View 文档中:

默认情况下,如果一个视图的 {@link #setFitsSystemWindows(boolean) fitsSystemWindows} 属性被设置,则该视图将消费系统窗口装饰并将其应用为视图的内边距。

同样的逻辑也适用于 RelativeLayout,因此我建议您在您的 Activity/Fragment 代码中添加以下行以跳过应用插入内容:

ViewCompat.setOnApplyWindowInsetsListener(relativeLayout) { _, insets -> insets }

因此,顶部填充将被删除。 为了看到它下面的视图,还需要设置透明状态栏颜色:

<item name="android:statusBarColor">@android:color/transparent</item>

0

fitSystemWindows 并不是将视图展开以适应系统窗口,而是为视图提供在期望的方式下处理它的机会。默认情况下,与 DrawerLayout 或 CoordinatorLayout 相反,ImageView 不接受此提议。您需要教 ImageView 如何使用系统窗口区域。尝试在您的 onCreate() 方法中添加类似以下内容的代码:

imageView.setOnApplyWindowInsetsListener((view, windowInsets) -> {
    view.setPaddingRelative(
            view.getPaddingStart(),
            windowInsets.getStableInsetTop(),
            view.getPaddingEnd(),
            view.getPaddingBottom()
    );
    return windowInsets;
});

你可能需要返回更改后的windowInsets对象,以便让其他具有“fitsSystemWindows”属性的视图一起正常工作。


我在这里找到了一个非常好的链接,介绍如何处理windowInsets:https://dev59.com/questions/WlwX5IYBdhLWcg3wnwrd#38929893 - demaksee

-1
因为 android:fitsSystemWindows="true" 会向 ImageView 添加内边距,因此 src 会在状态栏下面。内边距大小为插图(即状态栏高度)。 您可以使用 FitsSystemWindowsFrameLayout 来解决此问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接