Translucent/Transparent status bar + CoordinatorLayout + Toolbar + Fragment

I have following setup:

  • I'm using AppCompat
  • MainActivity, that holds a fragment and has a toolbar, that's hiding when scrolling down
  • Fragment with RecyclerView
  • all views that should fit the screen have the according android:fitsSystemWindows="true" in the xml layout
  • The problem is, I can't get the statusbar transparent in this case. What I do is following:

  • Create the activity and call setContent
  • Then I try to adjust the activity to programmatically get a translucent toolbar like following:

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public void themeNavAndStatusBar(Activity activity)
    {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
            return;
    
        Window w = activity.getWindow();
        w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        w.setFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        w.setFlags(
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
                WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        w.setNavigationBarColor(activity.getResources().getColor(android.R.color.transparent));
    
        w.setStatusBarColor(activity.getResources().getColor(android.R.color.transparent));
    }
    
  • Replace the placeholder in the activity ( @+id/frame_container ) with the fragment

  • The statusbar is solid colored in this case, and the views are not drawn underneath it... Why?

    What I want

    I want a toolbar, that is scrolled of the screen and hiding completely while the content underneath this toolbar should fitScreen and be drawn behind the transparent nav bar.

    Layouts

    Here's my main activity:

    <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/clMain"
        android:fitsSystemWindows="true"
        android:background="?attr/main_background_color"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.design.widget.AppBarLayout
            android:id="@+id/appBarLayout"
            android:fitsSystemWindows="true"
            android:background="@null"
            app:elevation="0dp"
            app:contentInsetLeft="0dp"
            app:contentInsetStart="0dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:elevation="4dp"
                android:theme="?actionBarThemeStyle"
                app:popupTheme="?actionBarPopupThemeStyle"
                app:layout_scrollFlags="scroll|enterAlways">
    
                <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content">
    
                    <LinearLayout
                        android:orientation="horizontal"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content">
    
                        <ImageView
                            android:id="@+id/ivToolbarDataSource"
                            android:layout_gravity="center_vertical"
                            android:layout_marginRight="2dp"
                            android:layout_width="24dp"
                            android:layout_height="24dp" />
    
                        <TextView
                            android:id="@+id/tvToolbarTitle"
                            style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
                            android:theme="?actionBarThemeStyle"
                            android:layout_gravity="center_vertical"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content" />
    
                    </LinearLayout>
    
                    <TextView
                        android:id="@+id/tvToolbarSubTitle"
                        style="@style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle"
                        android:theme="?actionBarThemeStyle"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content" />
    
                </LinearLayout>
    
    
    
            </android.support.v7.widget.Toolbar>
    
            <!-- BUG: http://stackoverflow.com/questions/30541409/coordinatorlayoutappbarlayout-does-not-draw-toolbar-properly -->
            <View
                android:layout_width="fill_parent"
                android:layout_height="1dp"/>
    
        </android.support.design.widget.AppBarLayout>
    
        <FrameLayout
            android:id="@+id/frame_container"
            android:fitsSystemWindows="true"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|right"
            android:layout_margin="32dp"
            android:src="@drawable/ic_local_offer_white_24dp"
            app:backgroundTint="?attr/colorPrimary"
            app:borderWidth="0dp"
            app:fabSize="normal"
            app:rippleColor="?attr/colorPrimaryDark"
            app:layout_anchorGravity="bottom|right|end"
            app:layout_behavior="com.test.classes.ScrollAwareFABBehavior"/>
    
    </android.support.design.widget.CoordinatorLayout>
    

    And here is my fragment, that will be placed in the main activity:

    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:fitsSystemWindows="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/srlImages"
            android:fitsSystemWindows="true"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <android.support.v7.widget.RecyclerView
                android:id="@+id/rvImages"
                android:fitsSystemWindows="true"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
    
        </android.support.v4.widget.SwipeRefreshLayout>
    
        <TextView
            android:id="@+id/tvEmpty"
            android:gravity="center"
            android:layout_centerInParent="true"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    </RelativeLayout>
    

    EDIT - Screenshots

    I use a light/dark base theme and theme everything by hand (because the user can select any color as primary/accent color), so don't mind that the toolbar is white (it's the default's theme background color and primary color). I added a black border as well so that you see where the activity ends...

  • First Screenshot: Shows the toolbar, nothing is scrolled
  • Second Screenshot: I just started scrolling => the toolbar now should scroll away
  • Third Screenshot: the main content should now scroll underneath the nav bar...
  • In the end, I'll of course make the toolbar and navbar semi transparent for a better visual effect...

    在这里输入图像描述在这里输入图像描述在这里输入图像描述


    tl;dr Set android:fitsSystemWindows="false" at least to the root CoordinatorLayout and to the inner fragment container, @frame_container .

    This might not be the final solution (ie there might be other fitsSystemWindows to change) so tell me if you have any problems.

    why

    When it comes to status bar, I think of fitsSystemWindows like so:

  • fitsSystemWindows="false" : draws the view normally, under the status bar because of the window flags you have set.
  • fitsSystemWindows="true" : draws the view normally, under the status bar because of the window flags you have set, but adds a top padding so that content is drawn below the status bar and they don't overlap.
  • In fact, in my opinion, the white you see is not the status bar color, but rather your CoordinatorLayout background. That is due to fitsSystemWindows="true" on the coordinator: it draws the background to the whole window, but adds top padding to the content so inner views are not covered by status bar.

    This is not what you want. Your inner content must be covered by the status bar, and so you have to set fitsSystemWindows="false" to the coordinator (so it won't apply top padding) and probably to the content itself.

    Once you get how it works, it is easy to debug and achieve the effect you are looking for. Actually, it is not. Years pass, but I still spend hours trying to figure out the right fitsSystemWindows combination, because most Views (in the support libraries at least) override the default behavior that I stated above, in ways that are mostly not intuitive. See this post for a small guide on how to use it.


    Edit your styles.xml (v21) , add the following style

     <style name="AppTheme.Home" parent="AppTheme.Base">
        <!-- Customize your theme here. -->
        <item name="android:windowTranslucentStatus">true</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:windowTranslucentNavigation">true</item>
    
    </style>
    

    You can change parent theme as per your liking, but now declare this theme in your AndroidManifest.xml file for a particular activity like this :

     <activity
            android:theme="@style/AppTheme.Home"
            android:name=".HomeActivity"
            android:launchMode="singleTop"
            android:screenOrientation="portrait" />
    

    This will let your content visible under the transparent actionbar.

    Now use the following to align your toolbar below the StatusBar properly, call this in your oncreate:

     toolbar.setPadding(0, getStatusBarHeight(), 0, 0);
    

    Get statusbar height using following :

    public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }
    

    Remove the following from your coordinator layout tags :

        android:fitsSystemWindows="true"
    

    Now in order to collapse your toolbar or hide it you may refer to following tutorial :

    http://antonioleiva.com/collapsing-toolbar-layout/
    

    Make sure you are using following version of design support library, as it is bug free :

        compile 'com.android.support:design:23.1.0'
    

    After reading your descriptions about your question, I thought styles of Google Photos matches your requirement.

    OK, there are just some tips for your question. After my test, it works.

  • If you want to show content behind status bar, you need add <item name="android:windowTranslucentStatus">true</item> into your style when Android version level is larger than 19(namely KitKat )
  • If you want to show content behind navigation bar, you need add <item name="android:windowTranslucentNavigation">true</item> into your style when Android version level is larger than 19(namely KitKat )
  • If you want to hide Toolbar smoothly when content is scrolled up and to show Toolbar smoothly when content is scrolled down, you need to add app:layout_collapseMode="parallax" into your Toolbar 's attributes based on your current codes.Of course, you need coordinate Toolbar with CollapsingToolbarLayout CoordinatorLayout and AppBarLayout .
  • 链接地址: http://www.djcxy.com/p/31472.html

    上一篇: 将片段附加到framelayout时如何删除空白区域

    下一篇: 半透明/透明状态栏+ CoordinatorLayout +工具栏+片段