半透明状态栏和工具栏

Posted

技术标签:

【中文标题】半透明状态栏和工具栏【英文标题】:Translucent status bar and toolbar 【发布时间】:2017-05-28 03:18:09 【问题描述】:

我想集成这样的东西:

我已经这样做了,但我似乎无法将 imageview 放在工具栏下方。没有工具栏,我可以让它在状态栏下,但是这两者结合起来是不可能的。

这是我的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:orientation="vertical"
    android:fitsSystemWindows="true"
    tools:context="com.project.android.PhotoActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/photo_tl"
        android:layout_
        android:layout_
        android:background="#59000000"
        tools:ignore="UnusedAttribute" />

    <ImageView
        android:id="@+id/photo_image"
        android:layout_
        android:layout_
        android:adjustViewBounds="true"
        android:scaleType="fitStart" />


</LinearLayout>

在我的活动中,我做了以下事情:

  getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

我还声明了一个 styles-v21.xml 文件:

<style name="Project.Photo" parent="Project.Light">
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">#59000000</item>
</style>

并将其设置为 PhotoActivity 的默认样式。 我已经尝试将工具栏放在 FrameLayout 中,但这样做我的工具栏只是隐藏起来,如下所示:

提前致谢。

已修复,但工具栏与状态栏重叠。无论如何要修复填充?如果我使用 android:fitsSystemWindows="true",状态栏不再是半透明的。

【问题讨论】:

不要忘记在每个版本的 android 上检查它,因为他们在每个主要版本都更改了 api。 同样的问题参考这个***.com/questions/29738510/… 在这里查看我的答案:***.com/a/41707177/1543839 【参考方案1】:

只需将工具栏高度更改为 wrap_content

<android.support.v7.widget.Toolbar
    android:id="@+id/photo_tl"
    android:layout_
    android:layout_
    android:background="#59000000"
    tools:ignore="UnusedAttribute" />

【讨论】:

【参考方案2】:

TLDR;您必须将工具栏包装在 LinearLayout 中。

我为使其工作所做的工作类似于@Akhilesh Kumar 的方法,但我将工具栏包裹在一个固定工具栏重叠的 LinearLayout 中。我还在那个 LinearLayout 中将 fitSystemWindows 设置为 true。

<FrameLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:fitsSystemWindows="true"
tools:context="com.project.android.PhotoActivity">

<ImageView
    android:id="@+id/photo_image"
    android:layout_
    android:layout_
    android:adjustViewBounds="true"
    android:scaleType="fitStart"/>

<LinearLayout

    android:id="@+id/content_card_image"
    android:layout_
    android:layout_
    android:orientation="vertical"
    android:fitsSystemWindows="true"
    >

    <android.support.v7.widget.Toolbar
        android:id="@+id/photo_tl"
        android:layout_
        android:layout_
        android:background="#59000000"
        tools:ignore="UnusedAttribute"/>

</LinearLayout>
</FrameLayout>

希望对你有帮助。

【讨论】:

另外,感谢这个答案:***.com/questions/33466295/… 半透明背景的值是 #66000000 而不是 #59。【参考方案3】:

如你所说,

“我已经尝试将工具栏放在 FrameLayout 中,但这样做我的工具栏只是隐藏起来,如下所示:”。

问题是在FrameLayout 中添加 childView 的顺序,您将 Toolbar 添加为第一个子项,然后添加 ImageView。这就是图像隐藏工具栏的原因。相反,FameLayout 内部的视图顺序应该是这样

<FrameLayout   
          xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"       
          android:layout_
          android:layout_
          android:fitsSystemWindows="true"
          tools:context="com.project.android.PhotoActivity">

          <ImageView
              android:id="@+id/photo_image"
              android:layout_
              android:layout_
              android:adjustViewBounds="true"
              android:scaleType="fitStart" />

          <android.support.v7.widget.Toolbar
              android:id="@+id/photo_tl"
              android:layout_
              android:layout_
              android:background="#59000000"
              tools:ignore="UnusedAttribute" />

    </FrameLayout>

同样对于 API 级别 >=19 ,您可以在style.xml 文件中添加此属性以使状态栏透明&lt;item name="android:windowTranslucentStatus"&gt;true&lt;/item&gt; 要在 statusBar 后面制作内容,请使用此链接https://developer.android.com/training/system-ui/status.html#behind

【讨论】:

【参考方案4】:

已修复,但工具栏与状态栏重叠。无论如何要修复填充?如果我使用 android:fitsSystemWindows="true",状态栏不再是半透明的。

我最近写了一篇关于 WindowInsets 的帖子,你可以check it out。我认为它会解决您的问题。

长话短说-您要做的就是通过ViewCompat.setOnApplyWindowInsetListener API 仅将窗口插图传递给Toolbar。但是您的 Toolbar 的父级应该通过窗口插图。在您的情况下,这不会发生,因为默认情况下 LinearLayout 和家庭布局不会这样做,您必须继承并覆盖 onApplyWindowInsets 方法。

我建议您阅读这篇文章,其中所有内容都描述得更准确。

【讨论】:

【参考方案5】:

不要将状态栏视为与您的应用分开的东西。图像出现在工具栏下方,因为您使用了 LinearLayout。如果您使用的是 RelativeLayout,您的图像将从与工具栏相同的高度开始。

现在为了使状态栏透明并且一切都从状态栏开始,请使用以下内容。

<style name="AppTheme.TranslucentStatusBar" >
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
</style>

为您的活动使用上述样式,一切都从状态栏开始。现在对于工具栏,您可以通过将状态栏的高度添加为工具栏的填充来增加工具栏的高度。这可以按如下方式完成:

toolbarContainer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() 
            @Override
            public void onGlobalLayout() 
                Rect frame = new Rect();
                getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
                toolbarContainer.setPadding(0, frame.top, 0, 0);
            
        );

您可以为状态栏设置颜色,并使用与工具栏上的 AlphaTransparency 相同的颜色。

getWindow().setStatusBarColor(ContextCompat.getColor(this, android.R.color.transparent));

现在您可以控制一切,包括状态栏和工具栏。

【讨论】:

【参考方案6】:

使用下面的代码

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/coordinator_layout"
    android:layout_
    android:layout_
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_
        android:layout_
        android:fitsSystemWindows="true">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_
            android:layout_
            android:fitsSystemWindows="true"
            app:contentScrim="@color/colorPrimary"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleTextAppearance="@style/AppTheme.CollapsingToolbarLayoutExpandedTextStyle"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <ImageView
                android:id="@+id/iv_backdrop"
                android:layout_
                android:layout_
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_
                android:layout_
                android:theme="@style/YourTheme"
                app:layout_collapseMode="pin" />

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

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

<!-- Rest of your view-->

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

【讨论】:

为了使图像适合整个屏幕(fitXY),这不起作用。仅当我将 AppBarLayout 扩展为 match_parent 时它才有效。有没有另一种方法可以使图像适合整个屏幕?或者这是错的? 另外我可以向上滑动图片!【参考方案7】:

我会从您的布局中删除Toolbar,并使用AppCompat.Theme 中的ActionBar 实现:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

然后,我会为半透明的ActionBar(在values/styles.xml

<style name="AppTheme.Transparent" parent="AppTheme">
    <item name="windowActionBarOverlay">true</item>
</style>

v21/styles.xml:

<style name="AppTheme.Transparent" parent="AppTheme">
    <item name="windowActionBarOverlay">true</item>
    <item name="android:windowTranslucentStatus">true</item>
</style>

我假设你的Activity 扩展了AppCompatActivity,所以你可以在onCreate() 中调用:

启用后退按钮:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);

用于设置半透明颜色:

getSupportActionBar().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this, R.color.yourTranslucentColor)));

删除您的ActionBar 标题:

getSupportActionBar().setDisplayShowTitleEnabled(false);

此外,我会将您的根 LinearLayout 更改为 CoordinatorLayout,因为它可以让您更好地控制您的布局(它是一个更强大的 FrameLayout)。

我使用的颜色是:

<color name="yourTranslucentColor">#29000000</color>

当然你应该记得把这个主题应用到你的ActivityAndroidManifest.xml

<activity
    android:name=".ui.activity.YourActivity"
    android:theme="@style/AppTheme.Transparent">
</activity>

通过执行所有这些步骤,您应该得到如下结果:

如果它适合你,请告诉我。

【讨论】:

【参考方案8】:

LinearLayout 会自动将ImageView 放在Toolbar 下方。

尝试改用RelativeLayout

【讨论】:

使用FrameLayout 可能会更好 @CharlesDurham 正如我所说,我已经尝试将工具栏放在 FrameLayout 和 RelativeLayout 中,但是这样做我的工具栏只是隐藏了。 @core_m 你能更新一下你是如何使用RelativeLayout和/或FrameLayout的吗? @core_m 您的工具栏没有隐藏。它绘制在ImageView 下方。您需要在布局文件中声明第二个工具栏。 @CharlesDurham 已修复,但工具栏与状态栏重叠。无论如何要修复填充?如果我使用 android:fitsSystemWindows="true",状态栏不再是半透明的。

以上是关于半透明状态栏和工具栏的主要内容,如果未能解决你的问题,请参考以下文章

android 4.4 的标签和半透明状态栏/导航出现问题

半透明/透明状态栏 + CoordinatorLayout + Toolbar + Fragment

无法将状态栏颜色更改为半透明黑色 [重复]

Android 沉浸式/透明式状态栏、导航栏

透明状态栏和沉浸式状态栏

android将工具栏扩展到半透明状态栏,同时将其他布局对象保留在系统视图中