Translucent status bar and toolbar

纵然是瞬间 提交于 2019-11-29 03:13:30

I would remove the Toolbar from your layout and use an implementation of an ActionBar from the AppCompat.Theme:

<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>

Then, I would create a new style for the semi-transparent ActionBar (in values/styles.xml:

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

And in v21/styles.xml:

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

I assume, that your Activity extends AppCompatActivity so then in onCreate() you can call:

For enabling a back button:

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

For setting your translucent color:

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

For removing your ActionBar title:

getSupportActionBar().setDisplayShowTitleEnabled(false);

What is more, I would change your root LinearLayout to CoordinatorLayout as it gives you more control over your layouts (it's a more powerful FrameLayout).

The color which I used is:

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

Of course you should remember to apply this theme to your Activity in the AndroidManifest.xml:

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

By doing all these steps you should get something like this:

Please let me know, if it works for you.

As you said,

"I've already tried putting the toolbar in a FrameLayout, but doing that my toolbar simply hides, like this:".


The problem with this is the order of adding childView in FrameLayout, you added Toolbar as first child and after that you added ImageView. this is why image hides the toolbar. Instead, the order of views inside FameLayout should be like this

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

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

          <android.support.v7.widget.Toolbar
              android:id="@+id/photo_tl"
              android:layout_width="match_parent"
              android:layout_height="?attr/actionBarSize"
              android:background="#59000000"
              tools:ignore="UnusedAttribute" />

    </FrameLayout>

Also for API level >=19 ,you can add this attribute in style.xml file to make statusBar transparent
<item name="android:windowTranslucentStatus">true</item>
For making content behind statusBar use this link

https://developer.android.com/training/system-ui/status.html#behind

Use code below

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

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:fitsSystemWindows="true">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            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_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?android:attr/actionBarSize"
                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>

LinearLayout will automatically place the ImageView below the Toolbar.

Try using a RelativeLayout instead.

Dont treat status bar as something separate from your app. Image is coming below the toolbar because you have used LinearLayout. Had you used RelativeLayout, your image would be starting at the same height as toolbar.

Now for making the statusbar transparent and for everything to start from under the statusbar use the following.

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

Use the above style for your activity and everything starts from under the statusbar. Now for the toolbar, you can increase the height of the toolbar by adding the height of the statusbar as padding to toolbar. This can be done as follows:

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);
            }
        });

You can set a color to statusbar and use the same color with AlphaTransparency on Toolbar.

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

Now you control everything including the statusbar and the toolbar.

TLDR; You have to wrap the toolbar in a LinearLayout.

What I did to make it work was similar to @Akhilesh Kumar's approach but I wrapped the toolbar in a LinearLayout which fixed the toolbar overlapping. I also put the fitsSystemWindows to true in that LinearLayout.

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

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

<LinearLayout

    android:id="@+id/content_card_image"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:fitsSystemWindows="true"
    >

    <android.support.v7.widget.Toolbar
        android:id="@+id/photo_tl"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="#59000000"
        tools:ignore="UnusedAttribute"/>

</LinearLayout>
</FrameLayout>

I hope it helps.

Got that fixed, but toolbar is overlapping the status bar. Is there anyway to fix the padding? If I use android:fitsSystemWindows="true", status bar isn't translucent anymore.

I've recently written a post about WindowInsets, you may check it out. I think it would resolve your issue.

Long story short - what you have to do is to pass window insets only to Toolbar via ViewCompat.setOnApplyWindowInsetListener API. But the parent of your Toolbar should pass the window insets. In your case that won't happen, because by default LinearLayout and family layouts won't do that, you have to subclass and override onApplyWindowInsets method.

I suggest you to read the article, where everything is described more precisely.

just change the toolbar height to wrap_content:

<android.support.v7.widget.Toolbar
    android:id="@+id/photo_tl"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#59000000"
    tools:ignore="UnusedAttribute" />
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!