Using windowTranslucentStatus with CollapsingToolb

2019-01-17 14:51发布

问题:

I'm trying to get a similar effect to what is seen on google play.

I've got the below layout to show a transparent toolbar with an image behind it. When the user scrolls there is a parallax effect on the imageview as it scrolls off the screen. The toolbar returns when ever the user scrolls up, with the imageview only returning when the user gets to the lop of the list.

This all works great.

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/main"
    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.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <android.support.design.widget.AppBarLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:background="@color/background_material_dark">
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbarLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:minHeight="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
            app:statusBarScrim="#09b"
            app:contentScrim="#09f">
            <ImageView
                android:id="@+id/img"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:src="@drawable/location_banner"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7"
                />
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_height="?attr/actionBarSize"
                android:layout_width="match_parent"
                app:layout_collapseMode="pin"
                android:fitsSystemWindows="true"
                app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"/>
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

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

The issue

When I set windowTranslucentStatus to true. The contents in the view move up to be under the status bar, but the contents of the CollapsingToolbarLayout moves up twice the height of the status bar(CollapsingToolbarLayout retains correct height).

This means some of the top of the image is cut off and the actionbar now appears under the status bar instead of below it. As a side effect of this there is now padding at the bottom of the CollapsingToolbarLayout the same height as the status bar

This is what it looks like without windowTranslucentStatus. Everything here works fine

windowTranslucentStatus set to true

User scrolling up from lower in list (not at top)

回答1:

Add fitsSystemWindows to layout and set to true.

Update

Sorry for my incomplete answer. You should add fitsSystemWindows="true" to layout xml like below codes.

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/main"
    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:fitsSystemWindows="true">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    <android.support.design.widget.AppBarLayout
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:background="@color/background_material_dark"
        android:fitsSystemWindows="true">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsingToolbarLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:minHeight="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
            app:statusBarScrim="#09b"
            app:contentScrim="#09f"
            android:fitsSystemWindows="true">

            <ImageView
                android:id="@+id/img"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:src="@drawable/location_banner"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="0.7"
                android:fitsSystemWindows="true"/>

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_height="?attr/actionBarSize"
                android:layout_width="match_parent"
                app:layout_collapseMode="pin"
                android:fitsSystemWindows="true"
                app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Dark"/>

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

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

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


回答2:

There has now been an update to the design library. I'm guessing that the issue posted above was a bug.

If you update the design library to the latest version this issue no longer occurs.

I have now removed all fitsSystemWindows="true" except for the ImageView (as that needs to display under the status bar).

I have also removed the minus padding from the Toolbar.

This is my theme for 21+

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowTranslucentStatus">true</item>
    <item name="android:windowActionBarOverlay">true</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:textColorPrimary">@android:color/white</item>
</style>

It all works as expected now



回答3:

Once the status bar is transparent and the free to use by the activity, the toolbar is pushed top to occupy that space. To fix this you need to manually move the toolbar to the original spot.

Add the below tags to the "android.support.v7.Widget.Toolbar" view :

android:layout_height="48dp" // Whatever the height of the toolbar you want
android:layout_marginTop="-48dp" // Negative of the height of the toolbar


回答4:

Extend the CoordinatorLayout and call setOnApplyWindowInsetsListener in your constructor to reset inset values. Here is the code:

public class CustomCoordinatorLayout extends CoordinatorLayout {
    public CustomCoordinatorLayout(Context context) {
        super(context);
        init();
    }

    public CustomCoordinatorLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CustomCoordinatorLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
            setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListener() {
                @Override
                public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
                    WindowInsets replaced = windowInsets.replaceSystemWindowInsets(0, 0, 0, 0);
                    return replaced;
                }
            });
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}


回答5:

The best way to achieve this is like Stimsoni said

Add android:fitsSystemWindows="true" to the CoordiatorLayout, AppBarLayout and ImageView

<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/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<android.support.design.widget.AppBarLayout
    android:id="@+id/appBar"
    android:fitsSystemWindows="true"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:contentScrim="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

        <ImageView
            android:id="@+id/background"
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:scaleType="centerCrop"
            android:fitsSystemWindows="true"
            app:layout_collapseMode="parallax"
            android:alpha="0.75"
            android:src="@drawable/foo"/>

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_collapseMode="pin"/>
    </android.support.design.widget.CollapsingToolbarLayout>        
</android.support.design.widget.AppBarLayout>...


回答6:

I have the same issue, but there is one thing i know.

If you what to have a transparent statusbar on a normal toolbar, you need to add a 16dp padding top.



回答7:

Just Change the color of status bar in Styles.XML(v21)

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

or remove the above line in that XML it work perfect.