it-swarm.com.de

Lutscher: hinter Statusleiste ziehen, wobei die Farbe auf transparent gesetzt ist

Ich habe meine StatusBar-Farbe für Lollipop nur in der folgenden Zeile in meinem Thema auf transparent gesetzt:

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

Jetzt muss ich dahinter zeichnen, aber ich bekomme keine Sicht dahinter. Ich weiß, wie man es mit der windowTranslucentStatus-Eigenschaft macht, aber ich möchte diese Eigenschaft nicht verwenden, da die Farbe der Statusbar, die auf transparent gesetzt ist, ignoriert wird.

114
alxscms

Methode 1:

Um eine vollständig transparente Statusleiste zu erhalten, müssen Sie statusBarColor verwenden, das nur in API 21 und höher verfügbar ist. windowTranslucentStatus ist in API 19 und höher verfügbar, fügt jedoch einen farbigen Hintergrund für die Statusleiste hinzu. Durch die Einstellung von windowTranslucentStatus wird jedoch eine Sache erreicht, die durch Ändern von statusBarColor in transparent nicht gilt: Sie setzt die Flags SYSTEM_UI_FLAG_LAYOUT_STABLE Und SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN. Der einfachste Weg, um den gleichen Effekt zu erzielen, besteht darin, diese Flags manuell zu setzen, wodurch die vom Android-Layoutsystem auferlegten Insets effektiv deaktiviert werden und Sie sich selbst überlassen müssen.

Sie rufen diese Zeile in Ihrer onCreate-Methode auf:

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

Stellen Sie sicher, dass Sie auch die Transparenz in /res/values-v21/styles.xml einstellen:

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

Oder stellen Sie die Transparenz programmgesteuert ein:

getWindow().setStatusBarColor(Color.TRANSPARENT);

Die gute Seite dieses Ansatzes ist, dass die gleichen Layouts und Designs auch für API 19 verwendet werden können, indem die transparente Statusleiste für die getönte, durchscheinende Statusleiste ausgetauscht wird.

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

Methode 2:

Wenn Sie nur ein Hintergrundbild unter Ihre Statusleiste malen müssen, anstatt eine Ansicht dahinter zu positionieren, können Sie einfach den Hintergrund des Motivs Ihrer Aktivität auf das gewünschte Bild setzen und die Transparenz der Statusleiste wie in Methode # einstellen. 1 Dies war die Methode, mit der ich die Screenshots für den Android Police-Artikel aus ein paar Monaten erstellt habe.

Methode # 3:

Wenn Sie die Standardeinfügungen des Systems für einige Layouts ignorieren müssen, während sie in anderen funktionieren, besteht die einzige Möglichkeit darin, mit der häufig verknüpften Klasse ScrimInsetsFrameLayout zu arbeiten. Natürlich sind einige der in dieser Klasse durchgeführten Aufgaben nicht für alle Szenarien erforderlich. Wenn Sie beispielsweise nicht beabsichtigen, die synthetische Statusleisten-Überlagerung zu verwenden, kommentieren Sie einfach alles in der init()-Methode aus und fügen Sie der attrs.xml-Datei nichts hinzu. Ich habe gesehen, wie dieser Ansatz funktioniert, aber ich denke, Sie werden feststellen, dass dies einige andere Implikationen mit sich bringt, die eine Menge Arbeit bedeuten, um herumzukommen.

Ich habe auch gesehen, dass Sie sich dagegen wehren, mehrere Layouts zu verpacken. Wenn ein Layout in ein anderes eingefügt wird, bei dem beide match_parent für Höhe und Breite haben, sind die Auswirkungen auf die Leistung zu trivial, um sich darüber Sorgen zu machen. Unabhängig davon können Sie diese Situation vollständig vermeiden, indem Sie die Klasse ändern, die sie von FrameLayout in einen beliebigen anderen Typ von Layout-Klasse erweitert. Es wird gut funktionieren.

341
Cody Toombs

Das hat für meinen Fall funktioniert


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

Weitere Informationen zum Arbeiten mit statusBars finden Sie unter youtube.com/watch?v=_mGDMVRO3iE


39
Michael

Versuchen Sie dieses Thema

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

Stellen Sie sicher, dass Ihr Layout festgelegt ist 

Android:fitsSystemWindows="false"
21

Anstatt 

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

Verwenden Sie folgendes:

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

Stellen Sie sicher, dass Sie die obere Auffüllung (standardmäßig hinzugefügt) in Ihrem 'MainActivity'-Layout entfernen.

Beachten Sie, dass dadurch die Statusleiste nicht vollständig transparent wird und es immer noch eine Überblendung "verblasstes Schwarz" über Ihrer Statusleiste gibt. 

10
Jeroen Mols

Die Lösung von Cody Toombs fast hat den Trick für mich getan. Ich bin nicht sicher, ob dies mit Xamarin zusammenhängt oder nicht, aber ich habe jetzt eine akzeptable Lösung:

Example

Das ist mein Setup:

Ich habe ein Android Projekt, in dem ich auf die Android.Support v4 und v7 Pakete verwiesen habe. Ich habe zwei Stile definiert:

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 zielt auf "MyStyle" ab:

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>

Und schließlich der Code in der Hauptaktivität:

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

Beachten Sie, dass ich das DrawsSystemBarBackgrounds-Flag gesetzt habe, das macht den Unterschied

Window.AddFlags (WindowManagerFlags.DrawsSystemBarBackgrounds); 

Ich habe viel Zeit damit verbracht, es richtig zu machen, eigentlich zu viel Zeit. Hoffentlich hilft diese Antwort jedem, der versucht, dasselbe zu erreichen.

8

Die Antwort von @Cody Toombs führt zu einem Problem, bei dem das Layout hinter der Navigationsleiste angezeigt wird. Was ich gefunden habe, ist die Verwendung von this von @Kriti 

hier ist das Kotlin-Code-Snippet für dasselbe:

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

Sie müssen auch hinzufügen

Android:fitsSystemWindows="false"

wurzelansicht Ihres Layouts.

1

Sie können ScrimInsetFrameLayout verwenden 

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

Android: fitsSystemWindows = "true" sollte beim Scrim-Layout eingestellt sein!

Ähnlich wie bei einigen der veröffentlichten Lösungen, aber in meinem Fall habe ich die Statusleiste transparent dargestellt und die Position der Aktionsleiste mit etwas negativem Rand festgelegt

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

Und ich habe in der Symbolleiste und der Stammansicht verwendet

Android:fitsSystemWindows="true"
1
jegumi

Ich hatte das gleiche Problem, also erstelle ich ImageView, das hinter der Statusleiste API 19+ zeichnet

Benutzerdefiniertes Bild hinter der Statusleiste einstellen 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);

}
1
Sumit

Alles, was Sie tun müssen, ist, diese Eigenschaften in Ihrem Design festzulegen

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

Es gibt eine gute Bibliothek StatusBarUtil from @laobie , die das einfache Zeichnen von Bildern in der Statusleiste erleichtern.

Fügen Sie einfach Ihren build.gradle hinzu:

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

Dann im Aktivitätssatz 

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

Im Layout

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

Für mehr Info download demo oder klone von github page und spiele mit allen Features.

Hinweis: Support KitKat und höher.

Hoffe das hilft jemand anderem!

0

Bei Android Studio 1.4 legt das Vorlagenprojekt mit Boiler Plate-Code das Thema Overlay in Ihrem AppbarLayout und/oder der Toolbar fest. Sie werden auch so eingestellt, dass sie durch fitSystemWindow attribute = true hinter der Statusleiste gerendert werden. Dadurch wird nur die Symbolleiste direkt unter der Statusleiste dargestellt, und alles andere wird unter der Symbolleiste dargestellt. Die oben genannten Lösungen funktionieren daher nicht von alleine. Sie müssen die folgenden Änderungen vornehmen.

  • Entfernen Sie das Overlay - Design oder ändern Sie es in ein nicht überlagertes Design für die Symbolleiste.
  • Fügen Sie den folgenden Code in Ihre styles-21.xml -Datei ein.

    @Android: Farbe/transparent

  • Weisen Sie dieses Design der Aktivität zu, die die Navigationsleiste in Der Datei AndroidManifest.xml enthält.

Dadurch wird das Navigationsfach hinter der transparenten Statusleiste gerendert.

0
Umer Farooq

Die akzeptierte Antwort funktionierte für mich mit einem CollapsingToolbarLayout. Es ist jedoch wichtig zu beachten, dass setSytstemUiVisibility() alle vorherigen Aufrufe dieser Funktion überschreibt. Wenn Sie diese Funktion also an einer anderen Stelle für dieselbe Ansicht verwenden, müssen Sie die Flags View.SYSTEM_UI_FLAG_LAYOUT_STABLE und View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN einfügen, da sie sonst mit dem neuen Aufruf überschrieben werden.

Dies war der Fall für mich, und als ich die beiden Flags an der anderen Stelle hinzufügte, an der ich setSystemUiVisibility() anrief, funktionierte die akzeptierte Antwort perfekt.

0
cpgreen2