Lollipop:色を透明に設定してstatusBarの後ろに描画します


142

LollipopのstatusBarの色を透明に設定したのは、テーマに次の行を追加した場合のみです。

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

今、背後に描画する必要がありますが、背後にビューを描画できません。私はwindowTranslucentStatusプロパティでそれを行う方法を知っていますが、透明に設定されたstatusBarの色を無視するため、このプロパティを使用したくありません。


2
次も使用できますandroid:fitsSystemWindows="true"
Aznix、2015

回答:


385

方法1:

完全に透明なステータスバーを実現するには、statusBarColorAPI 21以降でのみ使用できるを使用する必要があります。windowTranslucentStatusAPI 19以降で使用できますが、ステータスバーの背景が薄く表示されます。ただし、設定をwindowTranslucentStatus行うstatusBarColorと、transparentに変更しない場合の1つのことが実現されます。それは、フラグSYSTEM_UI_FLAG_LAYOUT_STABLESYSTEM_UI_FLAG_LAYOUT_FULLSCREENフラグを設定することです。同じ効果を得る最も簡単な方法は、これらのフラグを手動で設定することです。これにより、Androidレイアウトシステムによって課されたインセットが実質的に無効になり、自分で対処することができます。

onCreateメソッドで次の行を呼び出します。

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

/res/values-v21/styles.xmlにも透明度を設定してください:

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

または、プログラムで透明度を設定します。

getWindow().setStatusBarColor(Color.TRANSPARENT);

このアプローチの良い面は、色付きの半透明のステータスバーと透明なステータスバーを交換することで、API 19でも同じレイアウトとデザインを使用できることです。

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

方法#2:

ビューをその背後に配置するのではなく、ステータスバーの下に背景画像のみを描画する必要がある場合は、メソッドの背景に示すように、アクティビティのテーマの背景を目的の画像に設定し、ステータスバーの透明度を設定するだけです。 1。これは、数か月前にAndroid Policeの記事のスクリーンショットを作成するときに使用した方法です。

方法#3:

一部のレイアウトの標準システムインセットを無視して、他のレイアウトで機能させたままにする必要がある場合、実行可能な唯一の方法は、頻繁にリンクされるScrimInsetsFrameLayoutクラスを操作することです。もちろん、そのクラスで行われることの一部は、すべてのシナリオで必要なわけではありません。たとえば、合成ステータスバーオーバーレイを使用する予定がない場合は、init()メソッドのすべてをコメントアウトし、attrs.xmlファイルに何も追加しないでください。私はこのアプローチが機能するのを見てきましたが、それは回避するのに多くの作業になるかもしれないいくつかの他の影響をもたらすことがわかるでしょう。

また、複数のレイアウトをラップすることに反対していることもわかりました。1つのレイアウトを別のレイアウトの内側にラップする場合、両方ともmatch_parent高さと幅を持ち、パフォーマンスへの影響は些細なことなので心配する必要はありません。いずれにしても、拡張するクラスをFrameLayout他のタイプのLayoutクラスに変更することで、この状況を完全に回避できます。それはうまくいきます。


9
おかげで、SYSTEM_UI_FLAG_LAYOUT_STABLESYSTEM_UI_FLAG_LAYOUT_FULLSCREENフラグを設定することが私が探していた解決策でした。
alxscms

3
1か月間、最初の解決策を探しました。ありがとうございました!
NeoKree、2015

1
こんにちは。コードは完全に正常に動作します。しかし、フラグメントを終了するとき、変更をロールバックするにはどうすればよいですか?
TheOnlyAnil

3
これは動作しませんCollapsingToolbarLayoutし、Toolbar完全には半透明ではないステータスバーステーと:android:statusBarColor何の効果も取らない
コンスタンチンKonopko

ありがとう。その後、フルスクリーン以外のアクティビティに戻す場合は、developer.sonymobile.com / knowledge-base / tutorials /…を参照してください。
CoolMind

43

これは私のケースでうまくいきました


// Create/Set toolbar as actionbar
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

// Check if the version of Android is Lollipop or higher
if (Build.VERSION.SDK_INT >= 21) {

    // Set the status bar to dark-semi-transparentish
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
            WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

    // Set paddingTop of toolbar to height of status bar.
    // Fixes statusbar covers toolbar issue
    toolbar.setPadding(0, getStatusBarHeight(), 0, 0);
}

// A method to find height of the status bar
public int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

statusBarsの操作の詳細については、youtube.com / watch?v = _mGDMVRO3iEをご覧ください。



@TheOnlyAnilは、固定されたツールバーの高さを定義します:) "56dp"程度に見えるはずです
Michael

4
このようにステータスバーの高さを取得することは、完全にサポートされておらず、文書化されておらず、将来のバージョンでは確実に機能しなくなります。代わりにfitsSystemWindows = "true"を使用してください。
グレッグエニス2016年

1
ええと、私はそれをやっているので、時々あなたはちょうどしなければなりません。
グレッグエニス

2
これは、この講演ではクリス・Banes(Googleのエンジニア)によると、非常に悪い考えです:youtube.com/watch?v=_mGDMVRO3iE
マーティンMarconcini

1
@Michael FWIW、私は過去にこれを行ったことがありますが、これを行うにはWindowInsets api an(メソッド)を使用する必要があります。多くの不要なオーバーヘッド。Googleは常に80%完了しており、最後の20%は開発者に任せています。開発者は、それが実現するまでハッキングを行います。_(ツ)_ /¯
マーティンMarconcini

21

このテーマをお試しください

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="colorPrimaryDark">@android:color/transparent</item>
    <item name="colorPrimary">@color/md_blue_200</item>
    <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    <item name="android:statusBarColor">@android:color/transparent</item>
    <item name="android:windowTranslucentStatus">true</item>
</style>

レイアウトセットを確認してください

android:fitsSystemWindows="false"

4
設定android:fitsSystemWindows="false"はツールバーを半分にカットしています。
Hammad Nasir 2017

16

の代わりに

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

以下を使用します。

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

また、「MainActivity」レイアウトの上部のパディング(デフォルトで追加されています)を必ず削除してください。

これによってステータスバーが完全に透明になるわけではなく、ステータスバーの上に「色あせた黒い」オーバーレイが残ることに注意してください。


2
を使用する<item name="android:windowTranslucentStatus">true</item>と、ステータスバーの下に色あせた黒い背景がAndroidに表示されますが、これは私が探しているものではありません。この黒い色あせた背景を持たない方法はありますか?
alxscms 2015年

1
多くのことを試しましたが、色あせた黒い背景を削除する方法が見つかりません。したがって、私は、Androidでは(ScrimLayoutでは不可能であっても)それは不可能であると言って、私の研究を締めくくっています。ステータスバーが常に適切に読みやすくなるので、このような方法は理にかなっています。上記の回答を更新します。
Jeroen Mols

ステータスバーの後ろに描画できないように、透明な色を付けることができるのは非常に奇妙だと思います。この黒い色あせた背景を削除できないのは理にかなっているとおっしゃる理由を理解していますが、ステータスバーアイコンを表示したままにしておくのに十分注意するのは、それほど難しくありません。これは、透明なステータスバーandroidpolice.com/2014/07/04/…の使用を示すandroid policeの記事です。著者に連絡してみます。
alxscms 2015年

1
彼と連絡が取れるように。私もこれを行うことに非常に興味を持っています:)
Jeroen Mols

すごい!私の答えも更新しました。
Jeroen Mols、

9

Cody Toombsの解決策は、ほとんど私にとってはトリックでした。これがXamarinに関連するものかどうかはわかりませんが、今では許容できる解決策があります。

例

これは私のセットアップです:

Android.Support v4およびv7パッケージを参照しているAndroidプロジェクトがあります。2つのスタイルが定義されています。

values / styles.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<resources>
    <style name="MyStyle" parent="@style/Theme.AppCompat.Light.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>
    </style>
</resources>

values-v21 / styles.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<resources>
    <style name="MyStyle" parent="@style/Theme.AppCompat.Light.NoActionBar">
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>
</resources>

AndroidManifestは「MyStyle」をターゲットにしています。

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.agn.test.test">
    <uses-sdk android:minSdkVersion="10" />
    <application android:allowBackup="true" android:icon="@mipmap/icon" android:label="@string/app_name" android:theme="@style/MyStyle">
    </application>
</manifest>

そして最後に、メインアクティビティのコード:

[Activity (Label = "Test", MainLauncher = true, Icon = "@mipmap/icon")]
public class MainActivity : Activity
{
    protected override void OnCreate (Bundle savedInstanceState)
    {
        base.OnCreate (savedInstanceState);

        SetContentView (Resource.Layout.Main);
        //Resource.Layout.Main is just a regular layout, no additional flags. Make sure there is something in there like an imageView, so that you can see the overlay.

        var uiOptions = (int)Window.DecorView.SystemUiVisibility;
        uiOptions ^= (int)SystemUiFlags.LayoutStable;
        uiOptions ^= (int)SystemUiFlags.LayoutFullscreen;
        Window.DecorView.SystemUiVisibility = (StatusBarVisibility)uiOptions;

        Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds);
    }
}

DrawsSystemBarBackgroundsフラグを設定したことに注意してください。これにより、すべての違いが生まれます。

Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds); 

私はそれを正しくするために多くの時間を費やしました、実際にはあまりにも多くの時間。うまくいけば、この答えが同じことを達成しようとしている人を助けるでしょう。


1
android:windowTranslucentStatusAPIレベル19以上が必要ですが、values / styles.xmlでそれをandroid:minSdkVersion10の値で使用している可能性はありますか?
mradzinski 2017年

7

@Cody Toombsの答えは、ナビゲーションバーの背後にレイアウトをもたらす問題につながります。だから私が見つけたのは@Kritiによって与えられたこの解決策を使っていることです

これは同じためのKotlinコードスニペットです。

if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
    setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true)
}

if (Build.VERSION.SDK_INT >= 19) {
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
}

if (Build.VERSION.SDK_INT >= 21) {
    setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false)
    getWindow().setStatusBarColor(Color.TRANSPARENT)
}

private fun setWindowFlag(activity: Activity, bits: Int, on: Boolean) {

    val win: Window = activity.getWindow()

    val winParams: WindowManager.LayoutParams = win.getAttributes()
    if (on) {
        winParams.flags = winParams.flags or bits
    } else {
        winParams.flags = winParams.flags and bits.inv()
    }
    win.setAttributes(winParams)
}

また、追加する必要があります

android:fitsSystemWindows="false"

レイアウトのルートビュー。


3

私は同じ問題を抱えていたので、ステータスバーAPI 19以降の背後に描画するImageViewを作成します

ステータスバーgist.github.comの背後にカスタムイメージを設定する

public static void setTransparent(Activity activity, int imageRes) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        return;
    }
    // set flags
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        activity.getWindow().setStatusBarColor(Color.TRANSPARENT);
    } else {
        activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
    }

    // get root content of system window
    //ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
    // rootView.setFitsSystemWindows(true);
    // rootView.setClipToPadding(true);

    ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
    if (contentView.getChildCount() > 1) {
        contentView.removeViewAt(1);
    }

    // get status bar height
    int res = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
    int height = 0;
    if (res != 0)
        height = activity.getResources().getDimensionPixelSize(res);

    // create new imageview and set resource id
    ImageView image = new ImageView(activity);
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height);
    image.setLayoutParams(params);
    image.setImageResource(imageRes);
    image.setScaleType(ScaleType.MATRIX);

    // add image view to content view
    contentView.addView(image);
    // rootView.setFitsSystemWindows(true);

}

2

ScrimInsetFrameLayoutを使用できます

https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java

android:fitsSystemWindows = "true"はスクリムレイアウトに設定する必要があります!


そのクラスを見ましたが、RelativeLayout代わりにを使用したい場合はどうなりFrameLayoutますか?
alxscms 2015年

3
フレームレイアウト内で相対レイアウトを使用します。
Murtaza Khursheedフセイン2015

2
レイアウトにレイアウトをネストすることは、パフォーマンスに関して私にとって間違いなく解決策ではありません
alxscms

1
アプリのパフォーマンスは、さまざまな要因に左右されます。どうしようもない場合は試してみてください。Best of Luck
Murtaza Khursheed Hussain

私はあなたが何を意味するかを理解しますが、このカスタムフレームレイアウトに実装されているものをレイアウトに実装する方法がない場合は、別の解決策が必要です。しかし、とにかくありがとう
alxscms 2015年

1

投稿されたいくつかのソリューションと同様ですが、私の場合、ステータスバーを透明にし、アクションバーの位置を負のマージンで修正しました

if (Build.VERSION.SDK_INT >= 21) {
    getWindow().setStatusBarColor(Color.TRANSPARENT);
    FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) toolbar.getLayoutParams();
    lp.setMargins(0, -getStatusBarHeight(), 0, 0);
}

そして、ツールバーとルートビューで使用しました

android:fitsSystemWindows="true"

1
getStatusBarHeight()は標準ではありません
Roel

このメソッドは、@ mike-milla ...のソリューションに実装されています。public int getStatusBarHeight(){int result = 0; int resourceId = getResources()。getIdentifier( "status_bar_height"、 "dimen"、 "android"); if(resourceId> 0){result = getResources()。getDimensionPixelSize(resourceId); }結果を返します。}
jegumi 2016年

ありがとう。私はそうしました:AppBarLayout.LayoutParams lp =(AppBarLayout.LayoutParams)toolbar.getLayoutParams(); lp.topMargin + = getStatusBarHeight();
CoolMind 2016

1

良いライブラリがありStatusBarUtilから@laobieは、助けを簡単にステータスバーに画像を描画することは。

を追加してくださいbuild.gradle

compile 'com.jaeger.statusbarutil:library:1.4.0'

次に、アクティビティセットで

StatusBarUtil.setTranslucentForImageView(Activity activity, int statusBarAlpha, View viewNeedOffset)

レイアウトで

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:orientation="vertical">

    <ImageView
        android:layout_alignParentTop="true"
        android:layout_width="match_parent"
        android:adjustViewBounds="true"
        android:layout_height="wrap_content"
        android:src="@drawable/toolbar_bg"/>

    <android.support.design.widget.CoordinatorLayout
        android:id="@+id/view_need_offset"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@android:color/transparent"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

        <!-- Your layout code -->
    </android.support.design.widget.CoordinatorLayout>
</RelativeLayout>

詳細については、デモをダウンロードするか、githubページからクローンを作成して、すべての機能を試してください

注:KitKat以上をサポートします。

それが他の誰かを助けることを願っています!


0

Android Studio 1.4では、ボイラープレートコードを含むテンプレートプロジェクトがOverlayAppbarLayoutやツールバーにテーマを設定します。また、fitSystemWindow属性= true によってステータスバーの背後にレンダリングされるように設定されています。これにより、ツールバーのみがステータスバーの真下にレンダリングされ、それ以外はすべてツールバーの下にレンダリングされます。したがって、上記で提供されたソリューションはそれ自体では機能しません。次の変更を行う必要があります。

  • オーバーレイテーマを削除するか、ツールバーの非オーバーレイテーマに変更します。
  • 次のコードをstyles-21.xmlファイルに追加します。

    @android:color / transparent

  • このテーマを、AndroidManifest.xmlファイルのナビゲーションドロワーを含むアクティビティに割り当てます。

これにより、ナビゲーションドロワーが透明なステータスバーの背後にレンダリングされます。


0

あなたがする必要があるすべてはあなたのテーマでこれらのプロパティを設定することです

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

1
これにより、レイアウトがUIナビゲーションボタン(画面ナビゲーション付きのデバイス)の下に表示されるようになると確信しています。これにより、アプリで下部ナビゲーションビューにアクセスできなくなったため、Nexus
EpicPandaForce

0

受け入れられた回答は、CollapsingToolbarLayoutを使用して私に役立ちました。ただし、setSytstemUiVisibility()その関数への以前の呼び出しをオーバーライドすることに注意してください。したがって、同じビューの別の場所でその関数を使用している場合はView.SYSTEM_UI_FLAG_LAYOUT_STABLEView.SYSTEM_UI_FLAG_LAYOUT_FULLSCREENフラグとフラグを含める必要があります。そうしないと、新しい呼び出しでオーバーライドされます。

これは私にとっても当てはまり、私がを呼び出す他の場所に2つのフラグを追加するsetSystemUiVisibility()と、受け入れられた回答は完全に機能しました。


0

ここでさらに情報を追加します。最新のAndroid開発により、ステータスバーでの多くのケースの処理が非常に簡単になりました。以下は、からの私の観察ですstyles.xml

  1. 背景色:SDK 21以降では、多くの回答が述べられている<item name="android:windowTranslucentStatus">true</item> ように、ステータスバーが透明になり、UIの前に表示されます。あなたの活動はトップの全体のスペースを取ります。
  2. 背景色:SDK 21+の場合<item name="android:statusBarColor">@color/your_color</item>も、他に影響を与えることなく、ステータスバーに色を付けるだけです。

  3. ただし、以降のデバイス(Android M / +)では、アイコンが異なる色合いで表示されるようになりました。フォルダー内のstyles.xmlファイルを上書きしてvalues-23追加すると、OSはSDK 23 / +のアイコンに濃い灰色を与えることができます<item name="android:windowLightStatusBar">true</item>
    このようにして、ステータスバーの色が明るい場合に、ユーザーに表示されるステータスバーを提供します(Googleアプリの多くの背景が明るいにもかかわらず、アイコンが灰色がかった色で表示されていると考えてください)。
    ポイント#2でステータスバーに色を付ける場合は、これを使用することをお勧めします

  4. 最新のデバイスでは、SDK 29 / +には、ユーザーが制御できるシステム全体の明るいテーマと暗いテーマが付属しています。開発values-night者として、ユーザーに2つの異なるエクスペリエンスを提供するために、新しいフォルダーのスタイルファイルをオーバーライドすることも想定されています。
    ここでも、ポイント2が「ステータスバーの背景色」を提供するのに効果的であることがわかりました。しかし、システムは私のアプリのステータスバーアイコンの色を変更していませんでした。私の日バージョンのスタイルは明るいテーマで構成されているため、これはユーザーが低い可視性(明るい背景に白いアイコン)に苦しむことを意味します。
    この問題は、ポイント#3アプローチを使用するか、values-29フォルダー内のスタイルファイルを上書きして新しいものを使用することで解決できますapi <item name="android:enforceStatusBarContrast">true</item>。これにより、背景色が薄すぎる場合、アイコンに灰色がかった色合いが自動的に適用されます。


-1

これを達成するために使用するテーマは次のとおりです。

<style name="AppTheme" parent="@android:style/Theme.NoTitleBar">

    <!-- Default Background Screen -->
    <item name="android:background">@color/default_blue</item>
    <item name="android:windowTranslucentStatus">true</item>

</style>

1
奇妙な反対投票者がいます。ソリューションがあなたや他の誰かにとって正しかったとしても、彼らは別の答えに進む代わりに反対票を投じます。
CoolMind 2017

私が求めているのは説明です。説明なしでは投票できないと思います。
ドロイドクリス

私もそう思います。
CoolMind 2017

このバンドルでは、バックグラウンドオプションが正しく機能しないことを説明します。正解してください。
モロゾフ

うーん... Androidのどのバージョンを使用していますか?私は、Android Mにこの設定を使用しています
ドロイドクリス・

-3

適切な解決策は、アクティビティタグの下のXMLのプロパティを以下のスタイルに変更することです。うまくいく

  android:theme="@style/Theme.AppCompat.Light.NoActionBar"
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.