web-dev-qa-db-ja.com

ロリポップ:色を透明に設定してstatusBarの後ろに描画

テーマの次の行だけを使用して、LollipopのstatusBarの色を透明に設定しました。

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

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

119
alxscms

方法1:

完全に透明なステータスバーを実現するには、API 21以降でのみ利用可能なstatusBarColorを使用する必要があります。 windowTranslucentStatusは、API 19以降で使用できますが、ステータスバーの色付きの背景が追加されています。ただし、windowTranslucentStatusを設定しても、statusBarColorをtransparentに変更しても、SYSTEM_UI_FLAG_LAYOUT_STABLEおよびSYSTEM_UI_FLAG_LAYOUT_FULLSCREENフラグが設定されないという1つのことが達成されます。同じ効果を得る最も簡単な方法は手動でこれらのフラグを設定することです。これは事実上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クラスに拡張することで、この状況を完全に回避できます。それはちょうどうまくいくでしょう。

352
Cody Toombs

これは私の場合はうまくいきました


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

ステータスバーの使用方法の詳細については、 youtube.com/watch?v=_mGDMVRO3iE をご覧ください。


40
Michael

このテーマを試す

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

の代わりに

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

以下を使用してください。

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

そして、 'MainActivity'レイアウトの一番上のパディング(デフォルトで追加されている)を必ず削除してください。

ただし、これによってステータスバーが完全に透明になるわけではなく、ステータスバーの上に「フェードブラック」のオーバーレイが残ることに注意してください。

11
Jeroen Mols

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

Example

これは私の設定です:

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

そして最後にMain Activityのコードです。

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

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

8

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

}
3
Sumit

あなたはScrimInsetFrameLayoutを使うことができます

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

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

投稿された解決策のいくつかに似ていますが、私の場合はステータスバーを透明にし、アクションバーの位置を若干のマイナスのマージンで固定しました

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
jegumi

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

<item name="Android:windowTranslucentStatus">true</item>
<item name="Android:windowTranslucentNavigation">true</item>
0
Sudhir singh

簡単に画像を描くのに役立つ @ laobie からの良いライブラリ StatusBarUtil がありますステータスバーで。

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では、ボイラープレートコードを含むテンプレートプロジェクトは、AppbarLayoutまたはToolbar、あるいはその両方にOverlayテーマを設定します。それらはステータスバーの後ろにfitSystemWindow attribute = trueでレンダリングされるようにも設定されています。これにより、ツールバーのみがステータスバーの真下にレンダリングされ、その他はすべてツールバーの真下にレンダリングされます。そのため、上で提供された解決策はそれ自身ではうまくいきません。以下の変更を加える必要があります。

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

    @アンドロイド:カラー/透明

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

これにより、ナビゲーションパネルが透明なステータスバーの後ろに描画されます。

0
Umer Farooq

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

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

0
cpgreen2