在片段中使用 CoordinatorLayout 时如何使状态栏透明

Posted

技术标签:

【中文标题】在片段中使用 CoordinatorLayout 时如何使状态栏透明【英文标题】:How to make status bar transparent when using CoordinatorLayout in fragment 【发布时间】:2017-04-11 04:17:15 【问题描述】:

当我使用包含图像视图的 CoordinatorLayout 时,我遇到了一个问题 在片段中,我无法使状态栏透明并在状态栏下绘制图像视图(在活动中没关系)。

为了说明问题,我以cheesesquare为例。

cheesesquare 中有一个 CheeseDetailActivity 显示一些这样的内容(我想要的效果):

众所周知,在activity中制作这个效果很容易,我拿起关键代码:

styles.xml(v21)

activity_detail.xml

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

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

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_
        android:layout_
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:layout_collapseMode="pin" />

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

<LinearLayout
    android:layout_
    android:layout_
    android:orientation="vertical"
    android:paddingTop="24dp">

    <android.support.v7.widget.CardView
        android:layout_
        android:layout_
        android:layout_margin="@dimen/card_margin">

        <LinearLayout
            style="@style/Widget.CardContent"
            android:layout_
            android:layout_>

            <TextView
                android:layout_
                android:layout_
                android:text="Info"
                android:textAppearance="@style/TextAppearance.AppCompat.Title" />

            <TextView
                android:layout_
                android:layout_
                android:text="@string/cheese_ipsum" />

        </LinearLayout>

    </android.support.v7.widget.CardView>

    <android.support.v7.widget.CardView
        android:layout_
        android:layout_
        android:layout_marginBottom="@dimen/card_margin"
        android:layout_marginLeft="@dimen/card_margin"
        android:layout_marginRight="@dimen/card_margin">

        <LinearLayout
            style="@style/Widget.CardContent"
            android:layout_
            android:layout_>

            <TextView
                android:layout_
                android:layout_
                android:text="Friends"
                android:textAppearance="@style/TextAppearance.AppCompat.Title" />

            <TextView
                android:layout_
                android:layout_
                android:text="@string/cheese_ipsum" />

        </LinearLayout>

    </android.support.v7.widget.CardView>

    <android.support.v7.widget.CardView
        android:layout_
        android:layout_
        android:layout_marginBottom="@dimen/card_margin"
        android:layout_marginLeft="@dimen/card_margin"
        android:layout_marginRight="@dimen/card_margin">

        <LinearLayout
            style="@style/Widget.CardContent"
            android:layout_
            android:layout_>

            <TextView
                android:layout_
                android:layout_
                android:text="Related"
                android:textAppearance="@style/TextAppearance.AppCompat.Title" />

            <TextView
                android:layout_
                android:layout_
                android:text="@string/cheese_ipsum" />

        </LinearLayout>

    </android.support.v7.widget.CardView>

</LinearLayout>

问题

现在,出于某种原因,我想在片段中显示相同的内容,而不是在活动中。我尝试修改 cheesesquare 中的代码。我只是添加一个片段,style.xml 和 layout.xml 几乎相同.那么问题就存在了:

状态栏看起来不一样了!我确认样式和布局是相同的。所以我的问题是有什么不同?如何使状态栏透明?

编辑:

修改后的xmls

activity_main.xml(修改)

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

<!--<include layout="@layout/include_list_viewpager"/>-->

<FrameLayout
    android:id="@+id/fragment_container"
    android:layout_
    android:layout_>

    <fragment
        class="com.support.android.designlibdemo.MainFragment"
        android:layout_
        android:layout_/>

</FrameLayout>

<android.support.design.widget.NavigationView
    android:id="@+id/nav_view"
    android:layout_
    android:layout_
    android:layout_gravity="start"
    android:fitsSystemWindows="true"
    app:menu="@menu/drawer_view"/>

fragment_main.xml(添加)

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:tools="http://schemas.android.com/tools"
         android:layout_
         android:layout_
         tools:context="com.support.android.designlibdemo.MainFragment">

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

include_list_viewpager.xml(无修改)

style.xml(无修改)

activity_cheese_detail.xml(已删除)

fragment_cheese_detail.xml(已添加,只需复制源activity_cheese_detail.xml)

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

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_
    android:layout_
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:fitsSystemWindows="true">

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

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

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_
            android:layout_
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_collapseMode="pin" />

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

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

<android.support.v4.widget.NestedScrollView
    android:layout_
    android:layout_
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

</android.support.v4.widget.NestedScrollView>

<android.support.design.widget.FloatingActionButton
    android:layout_
    android:layout_
    app:layout_anchor="@id/appbar"
    app:layout_anchorGravity="bottom|right|end"
    android:src="@drawable/ic_discuss"
    android:layout_margin="@dimen/fab_margin"
    android:clickable="true"/>

【问题讨论】:

添加片段后请显示xmls。 好的,问题已编辑。 【参考方案1】:

你可以在 Java 代码中这样做

protected void makeTransperantStatusBar(boolean isTransperant) 
    if (isTransperant) 
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
     else 
        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    

如果你想要完全透明,你应该做以下事情

在您的主题中添加这些行

<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>

在你的协调器布局中设置这个标志

android:fitsSystemWindows="true"

最后在ActivityonCreate方法中添加这些行

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) 
        Window w = getWindow(); // in Activity's onCreate() for instance
        w.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
    

参考solution taken from here

【讨论】:

【参考方案2】:

删除或更改为 CoordinatorLayout 类型(使用 fitSystemWindows)CoordinatorLayout 子项的 FrameLayout 父项。

【讨论】:

FrameLayout 不会将 insets 信息分派给其子级。使用 CoordinatorLayout 类型而不是作为嵌套 CoordinatorLayout 的父级。【参考方案3】:

您必须使用 kitkat+ android 才能拥有此选项。

将此代码添加到您的主题中:

<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>

【讨论】:

以上是关于在片段中使用 CoordinatorLayout 时如何使状态栏透明的主要内容,如果未能解决你的问题,请参考以下文章

当它隐藏在另一个片段中时,以编程方式在 CoordinatorLayout 中显示 BottomNavigationView

FAB 的片段布局与 CoordinatorLayout 冲突

在CoordinatorLayout中,Supportmapfragment不工作。

Supportmapfragment 在 CoordinatorLayout 中不起作用

CoordinatorLayout 使用 ViewPager 的 RecyclerView

修复 CoordinatorLayout 中的底栏