Höhe der Statusleiste in Android

332

Wie hoch ist die Statusleiste in Android? Ist es immer das gleiche?

Aus meinen Messungen geht hervor, dass es 25 dp ist, aber ich bin mir nicht sicher, ob es auf allen Plattformen die gleiche Höhe hat.

(Ich möchte dies wissen, um einen Überblendungsübergang von einer Aktivität ohne Statusleiste zu einer Aktivität ohne Statusleiste ordnungsgemäß zu implementieren.)

hpique
quelle
Wenn Sie eine Überblendung durchführen, müssen Sie die Höhe der Statusleiste nicht kennen.
Stealthcopter
2
Ich brauche es, weil einige Elemente im Layout zentriert sind und ich möchte, dass sie ineinander übergehen.
Hpique
mögliches Duplikat der Höhe der Statusleiste?
Molnarm

Antworten:

363

Diese Frage wurde schon einmal beantwortet ... Höhe der Statusleiste?

Update ::

Aktuelle Methode:

OK, die Höhe der Statusleiste hängt von der Bildschirmgröße ab. Bei einem Gerät mit einer Bildschirmgröße von 240 x 320 beträgt die Höhe der Statusleiste beispielsweise 20 Pixel. Bei einem Gerät mit einer Bildschirmgröße von 320 x 480 beträgt die Höhe der Statusleiste 25 Pixel Bei Geräten mit 480 x 800 muss die Höhe der Statusleiste 38px betragen

Daher empfehle ich, dieses Skript zu verwenden, um die Höhe der Statusleiste zu ermitteln

Rect rectangle = new Rect();
Window window = getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
int statusBarHeight = rectangle.top;
int contentViewTop = 
    window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
int titleBarHeight= contentViewTop - statusBarHeight;

   Log.i("*** Elenasys :: ", "StatusBar Height= " + statusBarHeight + " , TitleBar Height = " + titleBarHeight); 

(alte Methode) onCreate()Verwenden Sie diese Methode , um die Höhe der Statusleiste für die Methode Ihrer Aktivität zu ermitteln:

public int getStatusBarHeight() { 
      int result = 0;
      int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
      if (resourceId > 0) {
          result = getResources().getDimensionPixelSize(resourceId);
      } 
      return result;
} 
Jorgesys
quelle
Nicht genau. Ich frage auch, ob ich davon ausgehen kann, dass die Statusleiste auf allen Geräten die gleiche Höhe hat.
Hpique
16
Oder Dip verwenden? Wenn es immer 25dip hat, wird der Code nicht benötigt.
Hpique
8
Sie können nicht davon ausgehen, dass es immer 25dp ist (überprüfen Sie die Höhe zum Beispiel auf dem Feuer).
DallinDyer
1
Funktioniert nicht in Runnable, die in onCreate () an view.post () übergeben wurde - return 0
Ixx
4
window.getDecorView().getWindowVisibleDisplayFrame(rectangle)Dies ist kein korrekter Weg, um die Höhe der Statusleiste zu ermitteln, wenn Sie sich im Mehrfenstermodus + Porträtdrehung + zweites Fenster befinden. Sie erhalten einen riesigen Wert (einschließlich der 1. Höhe).
Tuan Chau
211

Von allen Codebeispielen, die ich verwendet habe, um die Höhe der Statusleiste zu ermitteln, scheint das einzige, das tatsächlich in der onCreateMethode von a zu funktionieren scheint, Folgendes zu sein Activity:

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

Anscheinend wird die tatsächliche Höhe der Statusleiste als Android-Ressource beibehalten. Der obige Code kann einer ContextWrapperKlasse (z Activity. B. einer ) hinzugefügt werden .

Gefunden unter http://mrtn.me/blog/2012/03/17/get-the-height-of-the-status-bar-in-android/

Ben Clayton
quelle
Anstatt es hart zu codieren, ist es besser, dynamisch zu berechnen. Die obige Methode hat bei mir funktioniert!
Alchemist
sollten Sie nicht stattdessen getDimension (...) verwenden?
Android-Entwickler
6
Ein Wort der Vorsicht - dies funktioniert nicht auf allen Geräten. Beispielsweise wird beim Transformator TF201 (sowie bei TF101, TF300 und einigen anderen Geräten) die Höhe als 25 angegeben, wenn keine Statusleiste vorhanden ist.
Błażej Czapp
4
Aufgrund der obigen Kommentare scheint es mir, dass der Code Ihnen sagt, wie hoch die Statusleiste auf einem bestimmten Gerät ist - nicht wie hoch sie auf einer bestimmten Aktivität ist (die möglicherweise keine Statusleiste hat).
benommen
In XML kann die Dimen-Ressource "@android: dimen / status_bar_height" verwendet werden. <! - Höhe der Statusleiste in der Quelldatei des Android-Systems definiert -> <dimen name = "status_bar_height"> 24dp </ dimension>. Sie können es jedoch nicht direkt in Ihrem App-Projekt referenzieren. Sie müssen also Code verwenden.
Tshunglee
48

Auf MDPI-Geräten beträgt die Statusleiste 25 Pixel. Wir können dies als Basis verwenden und es mit der Dichte (aufgerundet) multiplizieren, um die Höhe der Statusleiste auf jedem Gerät zu erhalten:

int statusBarHeight = Math.ceil(25 * context.getResources().getDisplayMetrics().density);

Als Referenz: ldpi = 0,75, mdpi = 1, hdpi = 1,5, xhdpi = 2

Grantland Chew
quelle
6
Dies gilt für Geräte mit einer Statusleiste. Beachten Sie, dass seit dem Schreiben des oben Gesagten nicht alle Geräte über eines verfügen. Insbesondere können Geräte, auf denen ICS ausgeführt wird, unten eine kombinierte Status- / Navigationsleiste und oben überhaupt nichts haben. In diesem Fall möchten Sie für die meisten Programmierzwecke der Statusleiste eine Höhe von Null zuweisen, aber die obige Formulierung würde Ihnen eine Größe ungleich Null geben.
Carl
1
Außerdem ist der 25px-Wert nicht für alle mdpi-Geräte korrekt. Sie kann je nach API-Ebene variieren. Zum Beispiel meldet das 10.1 WXGA Tablet Emulator-Gerät 25px bei API 16 & 19, aber 24px bei API 24.
jk7
Funktioniert das mit Lochblenden und Kerben?
siehe
48

Das Hardcodieren der Größe oder das Verwenden von Reflexion, um den Wert von zu erhalten, status_bar_heightwird als schlechte Praxis angesehen. Chris Banes hat auf der Droidcon New York darüber gesprochen . Die empfohlene Methode zum Abrufen der Größe der Statusleiste ist der OnApplyWindowInsetsListener :

myView.setOnApplyWindowInsetsListener { view, insets -> {
  val statusBarSize = insets.systemWindowInsetTop
  return insets
}

Dies wurde in API 20 hinzugefügt und wird auch über ViewAppCompat zurückportiert .

Niklas
quelle
Dies ist die genaueste Antwort heute
Keith
Für mich wird dies nur einmal ausgelöst, wenn ich Fragmente über Bottom Nav habe. Wenn ich das Fragment erneut ersetze, wird dieser Listener nicht aufgerufen. Gibt es auch einen kompatiblen Getter?
urSus
73
Und doch ist diese API schrecklich, weil die Anzahl der WTF / Gotchas hinter den Kulissen riesig ist. Sie würden denken, dass Sie dies mit jeder Ansicht tun können, aber nein, Sie müssen bestimmte Dinge überschreiben und sicherstellen, dass SIE die Einfügungen an Ihre Kinder weitergeben (??), da EINIGE ViewGroups (Materialdesign) und ALLE ANDEREN ( lineares Layout? ConstraintLayout? Hallo?). Anstelle des Systems mit Window.getStatusBarSize () ... müssen wir einen FREAKING LISTENER abonnieren ... gehen Sie nach Hause Android, Sie sind betrunken. Einfach die Größe fest codieren, bis Google aufwacht, wir sind im Jahr 2018. Ich hoffe, Chris Banes sieht dies eines Tages…
Martin Marconcini
In meinem Fall wird es nicht gefeuert. Ich habe es Aktivität # onCreated gesetzt. Habe ich etwas falsch gemacht? Warum verwenden wir nicht mView.getRootWindowInsets ()?
Adil Aliyev
34

Ich habe einige Lösungen zusammengeführt:

public static int getStatusBarHeight(final Context context) {
    final Resources resources = context.getResources();
    final int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0)
        return resources.getDimensionPixelSize(resourceId);
    else
        return (int) Math.ceil((VERSION.SDK_INT >= VERSION_CODES.M ? 24 : 25) * resources.getDisplayMetrics().density);
    }

eine andere Alternative:

    final View view = findViewById(android.R.id.content);
    runJustBeforeBeingDrawn(view, new Runnable() {
        @Override
        public void run() {
            int statusBarHeight = getResources().getDisplayMetrics().heightPixels - view.getMeasuredHeight();
        }
    });

BEARBEITEN: Alternative zu runJustBeforeBeingDrawn: https://stackoverflow.com/a/28136027/878126

Android-Entwickler
quelle
getResources (). getDisplayMetrics (). heightPixels -getActivity (). findViewById (android.R.id.content) .getMeasuredHeight () funktioniert nicht in android lolipop
abbasalim
@ ArMo372 Aktualisierte Antwort. Es ist nur so, dass die Ansicht zuerst die Messung bestehen muss. Sie müssen runJustBeforeBeingDrawn nicht verwenden, wenn Sie es bereits bestanden haben. Sie werden es nur in zu frühen Fällen verwenden.
Android-Entwickler
28

Gemäß den Google-Designrichtlinien ; Die Höhe der Statusleiste beträgt 24 dp.

Wenn Sie die Höhe der Statusleiste in Pixel erhalten möchten, können Sie die folgende Methode verwenden:

private static int statusBarHeight(android.content.res.Resources res) {
    return (int) (24 * res.getDisplayMetrics().density);
}

die von Aktivität mit aufgerufen werden kann mit:

statusBarHeight(getResources());
Rashid
quelle
18
Bis Marshmallow waren es 25dp. Seit Marshmallow ist es 24dp.
Eugen Pechanec
1
Dies ist im Wesentlichen eine Hardcodierung des Wertes - der keine Designänderungen zulässt
siliconeagle
1
und berücksichtigt nicht die Tatsache, dass die Statusleiste nicht in den gleichen Fällen angezeigt wird
jk7
19

Die Standardhöhe war 25dp. Mit Android Marshmallow (API 23) wurde die Höhe auf 24dp reduziert.

Update: Bitte beachten Sie, dass die Verwendung einer statischen Höhe für die Statusleiste seit Beginn des Zeitalters der Kerben und Lochkameras nicht mehr funktioniert. Bitte verwenden Sie stattdessen Fenstereinsätze!

crysxd
quelle
1
Süss! Ich habe gerade eine dimension.xml speziell für API Level 23+ erstellt, in der ich die Höhe als 24dp fest codiert habe.
Jemand irgendwo
18

Dies funktioniert auch mit dem Refrence- Link

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

Ich habe das gleiche Problem, dass ich die Höhe der Statusleiste in einem onCreate abrufen muss. Das funktioniert bei mir.

private static final int LOW_DPI_STATUS_BAR_HEIGHT = 19;

private static final int MEDIUM_DPI_STATUS_BAR_HEIGHT = 25;

private static final int HIGH_DPI_STATUS_BAR_HEIGHT = 38;

Innerhalb des onCreate:

DisplayMetrics displayMetrics = new DisplayMetrics();
((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics);

int statusBarHeight;

switch (displayMetrics.densityDpi) {
    case DisplayMetrics.DENSITY_HIGH:
        statusBarHeight = HIGH_DPI_STATUS_BAR_HEIGHT;
        break;
    case DisplayMetrics.DENSITY_MEDIUM:
        statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
        break;
    case DisplayMetrics.DENSITY_LOW:
        statusBarHeight = LOW_DPI_STATUS_BAR_HEIGHT;
        break;
    default:
        statusBarHeight = MEDIUM_DPI_STATUS_BAR_HEIGHT;
}

Sehen:

http://developer.android.com/reference/android/util/DisplayMetrics.html http://developer.android.com/guide/practices/ui_guidelines/icon_design.html

benhylau
quelle
3
Ich mag Ihre Idee, dichtegesteuerte Werte zu verwenden. Wenn Sie den Code an mehreren Stellen verwenden (oder andere dichtebezogene Werte verwenden), ziehe ich es vor, die Arbeit auf das System zu verlagern und die Werte in einer Dimen-Ressource zu speichern, wodurch der Wechsel unnötig wird. Sie müssen für jede Dichte einen dimensionsspezifischen Ordner und eine Ressourcendatei erstellen. final Resources res = context.getResources (); int statusbarHeight = 0; try {statusbarHeight = res.getDimensionPixelSize (R.dimen.android_statusbar_height); } catch (NotFoundException e) {}
ProjectJourneyman
5
Das Hardcodieren dieser Werte ist gefährlich. Was passiert, wenn sie sich in einer späteren Plattformversion ändern?
David Snabel-Caunt
Ich denke, anstatt fest codierte Pixelgrößen (eine für jede Dichte) zu verwenden, ist es besser, "25dp" zu verwenden.
Android-Entwickler
12

Ja, wenn ich es mit View versuche, liefert es das Ergebnis von 25px. Hier ist der gesamte Code:

public class SpinActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LinearLayout lySpin = new LinearLayout(this);
        lySpin.setOrientation(LinearLayout.VERTICAL);       
        lySpin.post(new Runnable()
        {
            public void run()
            {
                Rect rect = new Rect();
                Window window = getWindow();
                window.getDecorView().getWindowVisibleDisplayFrame(rect);
                int statusBarHeight = rect.top;
                int contentViewTop = 
                    window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
                int titleBarHeight = contentViewTop - statusBarHeight;
                System.out.println("TitleBarHeight: " + titleBarHeight 
                    + ", StatusBarHeight: " + statusBarHeight);
            }
        }
    }
}
Braj
quelle
Der obige Code funktioniert für mich, wenn ich ein neues lineares Layout erstelle, wie Sie es oben getan haben, aber wenn ich viewbyid für den lySpin aus der XML finde. dann wird null zurückgegeben. Ich verstehe nicht, dass es sich so verhält.
Shaista Naaz
Weil das Layout in onCreate seine Größe noch nicht kennt, weil es noch nicht fertig gezeichnet wurde. Normalerweise poste ich ein Runnable auf dem UI-Thread von onCreate, wodurch die UI Zeit hat, sich selbst zu zeichnen.
Jason Robinson
8

240 x 320 - 20 Pixel

320 x 480 - 25 Pixel

480 x 800 + - 38 Pixel

Denis
quelle
3
Dies ist nicht mehr korrekt. Verwenden Sie eine Methode zum Messen der Statusleiste.
Michael
7

Versuche dies:

    Rect rect = new Rect();
    Window win = this.getWindow();
    win.getDecorView().getWindowVisibleDisplayFrame(rect);
    int statusBarHeight = rect.top;
    int contentViewTop = win.findViewById(Window.ID_ANDROID_CONTENT).getTop();
    int titleBarHeight = contentViewTop - statusBarHeight;
    Log.d("ID-ANDROID-CONTENT", "titleBarHeight = " + titleBarHeight );

Bei der onCreate-Methode für die Aktivität hat es bei mir nicht funktioniert, aber beim Einfügen in einen onClickListener und bei einer Messung von 25

Martyn
quelle
Ich vermute, dass zu dem Zeitpunkt, als er in onCreate () getestet hat, die Statusleiste noch nicht erstellt wurde. Im Gegensatz dazu hatte die Leiste beim manuellen Klicken zum Aktivieren seines onClickListener () - Codes bereits viel Zeit zum Nachdenken, und er konnte ihre Größe abrufen.
Carl
6

Die Höhe der Statusleiste beträgt 24dp in Android 6.0

 <!-- Height of the status bar -->
 <dimen name="status_bar_height">24dp</dimen>
 <!-- Height of the bottom navigation / system bar. -->
 <dimen name="navigation_bar_height">48dp</dimen>

Die Antwort finden Sie im Quellcode: Frameworks \ Base \ Core \ Res \ Res \ Values ​​\ Dimens.xml

Xiaoyuan Hu
quelle
Gibt es eine Möglichkeit, diese Ressource in unsere XML-Dateien aufzunehmen? @android:dimen/status_bar_heightfunktioniert nicht bei mir
Patrick
4

Um dies zu lösen, habe ich einen Kombinationsansatz verwendet. Dies ist erforderlich, da auf Tablets die Systemleiste bereits die Pixel subtrahiert, wenn display.getHeight () aufgerufen wird. Also überprüfe ich zuerst, ob eine Systemleiste vorhanden ist, und dann Ben Claytons Ansatz, der auf Telefonen gut funktioniert.

public int getStatusBarHeight() {
    int statusBarHeight = 0;

    if (!hasOnScreenSystemBar()) {
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            statusBarHeight = getResources().getDimensionPixelSize(resourceId);
        }
    }

    return statusBarHeight;
}

private boolean hasOnScreenSystemBar() {
    Display display = getWindowManager().getDefaultDisplay();
    int rawDisplayHeight = 0;
    try {
        Method getRawHeight = Display.class.getMethod("getRawHeight");
        rawDisplayHeight = (Integer) getRawHeight.invoke(display);
    } catch (Exception ex) {
    }

    int UIRequestedHeight = display.getHeight();

    return rawDisplayHeight - UIRequestedHeight > 0;
}
Rutger
quelle
3

Dank @Niklas +1 ist dies der richtige Weg.

public class MyActivity extends Activity implements android.support.v4.View.OnApplyWindowInsetsListener {

    Rect windowInsets;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.my_activity);

        View rootview = findViewById(android.R.id.content);

        android.support.v4.View.ViewCompat.setOnApplyWindowInsetsListener(rootview, this);
    }

    android.support.v4.View.WindowInsetsCompat android.support.v4.View.OnApplyWindowInsetsListener.OnApplyWindowInsets(View v, android.support.v4.View.WindowInsetsCompat insets)
    {
        windowInsets = new Rect();
        windowInsets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
        //StatusBarHeight = insets.getSystemWindowInsetTop();

        //Refresh/Adjust view accordingly

        return insets;
    }
}

Bitte entschuldigen Sie, wenn der Code nicht 100% korrekt ist, konvertieren Sie ihn von Xamarin C #, aber dies ist das Richtige. Funktioniert mit Kerben usw.

Pierre
quelle
2

Umgeschaltete Vollbildlösung:

Diese Lösung mag wie eine Problemumgehung aussehen, berücksichtigt jedoch tatsächlich, ob Ihre App im Vollbildmodus angezeigt wird (auch bekannt als Ausblenden der Statusleiste) oder nicht:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point(); display.getSize(size);
int barheight = size.y - findViewById(R.id.rootView).getHeight();

Wenn Ihre App derzeit im Vollbildmodus angezeigt barheightwird, entspricht dies 0.

Persönlich musste ich dies verwenden, um absolute TouchEvent-Koordinaten zu korrigieren, um die Statusleiste wie folgt zu berücksichtigen:

@Override
public boolean onTouch(View view,MotionEvent event) {
    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point(); display.getSize(size);
    int YCoord = (int)event.getRawY() - size.y + rootView.getHeight());
}

Und das wird die absolute y-Koordinate erhalten, ob die App Vollbild ist oder nicht.

Genießen

Aaron Gillion
quelle
Danke, dies war die einzige Lösung, die für mich funktioniert hat, wenn auch die Android-Tastatur angezeigt wird.
Thiago Moura
2

Unter Android 4.1 und höher können Sie festlegen, dass der Inhalt Ihrer Anwendung hinter der Statusleiste angezeigt wird, damit die Größe des Inhalts nicht geändert wird, wenn die Statusleiste ausgeblendet und angezeigt wird. Verwenden Sie dazu SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN. Möglicherweise müssen Sie auch SYSTEM_UI_FLAG_LAYOUT_STABLE verwenden, damit Ihre App ein stabiles Layout beibehält.

Wenn Sie diesen Ansatz verwenden, liegt es in Ihrer Verantwortung, sicherzustellen, dass kritische Teile der Benutzeroberfläche Ihrer App (z. B. die in einer Maps-Anwendung integrierten Steuerelemente) nicht von Systemleisten abgedeckt werden. Dies könnte Ihre App unbrauchbar machen. In den meisten Fällen können Sie dies tun, indem Sie das Attribut android: fitSystemWindows zu Ihrer XML-Layoutdatei hinzufügen, das auf true festgelegt ist. Dadurch wird der Abstand der übergeordneten ViewGroup angepasst, um Platz für die Systemfenster zu lassen. Dies ist für die meisten Anwendungen ausreichend.

In einigen Fällen müssen Sie jedoch möglicherweise die Standardauffüllung ändern, um das gewünschte Layout für Ihre App zu erhalten. Überschreiben Sie fitSystemWindows (Rect-Einfügungen), um direkt zu steuern, wie Ihr Inhalt relativ zu den Systemleisten angeordnet ist (die einen Bereich einnehmen, der als "Inhaltseinfügungen" des Fensters bezeichnet wird). Die Methode fitSystemWindows () wird von der Ansichtshierarchie aufgerufen, wenn sich die Inhaltseinfügungen für ein Fenster geändert haben, damit das Fenster seinen Inhalt entsprechend anpassen kann. Durch Überschreiben dieser Methode können Sie die Einfügungen (und damit das Layout Ihrer App) beliebig behandeln.

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

Xiaoyuan Hu
quelle
1

Wenn Sie genau die Größe VS Höhe kennen

mögen

Bei einem Gerät mit einer Bildschirmgröße von 320 x 480 beträgt die Statusleistenhöhe beispielsweise 25 Pixel. Bei einem Gerät mit 480 x 800 muss die Statusleistenhöhe 38 Pixel betragen

Dann können Sie einfach die Breite Ihrer Ansicht / die Bildschirmgröße abrufen. Sie können einfach eine if else-Anweisung verwenden, um die Höhe der Statusleiste abzurufen

Steven Shih
quelle
Nach meiner Erfahrung scheint die Höhe eher auf der Dichte als auf der Bildschirmgröße zu beruhen. Natürlich hängt die Dichte selbst typischerweise von der Bildschirmgröße ab, daher besteht eine indirekte Beziehung. Mein alter Moto Droid hat zum Beispiel ein 480x854 (anstatt 480x800) Display und die Statusleiste ist ebenfalls 38 Pixel hoch.
Carl
Sie erfanden dp dafür (dichteunabhängige Pixel)
Roel
1

Der Grund, warum die Top-Antwort für einige Benutzer nicht funktioniert, liegt darin, dass Sie die Abmessungen einer Ansicht erst abrufen können, wenn sie zum Rendern bereit ist. Verwenden Sie ein OnGlobalLayoutListener, um die angegebenen Abmessungen zu erhalten, wenn Sie tatsächlich können:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final ViewGroup decorView = (ViewGroup) this.getWindow().getDecorView();
    decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT >= 16) {
                decorView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                // Nice one, Google
                decorView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
            Rect rect = new Rect();
            decorView.getWindowVisibleDisplayFrame(rect);
            rect.top; // This is the height of the status bar
        }
    }
}

Dies ist die zuverlässigste Methode.

user1112789
quelle
1
@androiddeveloper OnGlobal! = GlobalOn
Marihnz0r
@ Marihnz0r Wie seltsam. Was ist damit los?
Android-Entwickler
@androiddeveloper Ich weiß es nicht, aber ich habe zufällig genauso gedacht wie vor ein paar Tagen. Siehe: stackoverflow.com/a/19216041/4587214
Marihnz0r
@ Marihnz0r Also machen beide das Gleiche. Erinnert mich an andere Fälle, in denen sie einen neuen Namen für ein bereits vorhandenes Material vergeben und das vorherige abgelehnt haben. Beispiel "fill_parent" vs "match_parent": developer.android.com/reference/android/view/…
Android-Entwickler
1

Da der Mehrfenstermodus jetzt verfügbar ist, hat Ihre App möglicherweise keine Statusleiste oben.

Die folgende Lösung behandelt alle Fälle automatisch für Sie.

android:fitsSystemWindows="true"

oder programmatisch

findViewById(R.id.your_root_view).setFitsSystemWindows(true);

Sie können auch Root-Ansicht von erhalten

findViewById(android.R.id.content).getRootView();
or
getWindow().getDecorView().findViewById(android.R.id.content)

Weitere Informationen zum Abrufen der Root-Ansicht finden Sie unter https://stackoverflow.com/a/4488149/9640177

mayank1513
quelle
0

Dieses Problem wurde kürzlich für mich aufgrund der Kerbe in meinem Pixel 3XL relevant. Ich mochte die Lösung für Android-Entwickler sehr , aber ich wollte in der Lage sein, die Höhe der Statusleiste nach Belieben zu ermitteln, da dies speziell für eine Vollbildanimation erforderlich war, die ich abspielen musste. Die folgende Funktion ermöglichte eine zuverlässige Abfrage:

private val DEFAULT_INSET = 96
fun getInsets(view: View?): Int {
     var inset = DEFAULT_INSET
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {//Safe because only P supports notches
          inset = view?.rootWindowInsets?.stableInsetTop ?: DEFAULT_INSET
     }
     return inset
}

fun blurView(rootView: View?, a: SpacesActivity?) {
    val screenBitmap = getBitmapFromView(rootView!!)
    val heightDifference = getInsets(rootView)
    val croppedMap = Bitmap.createBitmap(
                    screenBitmap, 0, heightDifference,
                    screenBitmap.width,
                    screenBitmap.height - heightDifference)
    val blurredScreen = blurBitmap(croppedMap)
    if (blurredScreen != null) {
         val myDrawable = BitmapDrawable(a!!.resources, blurredScreen)
         a.errorHudFrameLayout?.background = myDrawable
         a.appBarLayout?.visibility = View.INVISIBLE
   }
}

Und dann in der Aktivitätsklasse:

fun blurView() {
    this.runOnUiThread {
        Helper.blurView(this)
    }
}

Sie möchten natürlich eine schwache Referenz der Aktivität an den statischen Parameter der Helper-Klassenmethode übergeben, aber der Kürze halber habe ich in diesem Beispiel darauf verzichtet. Die blurBitmapund errorHudFrameLayoutwerden aus demselben Grund weggelassen, da sie nicht direkt mit dem Abrufen der Höhe der Statusleiste zusammenhängen.

James Jordan Taylor
quelle
Wenn es für Android P und höher ist, warum mit Android M überprüfen? Was würden Sie auch tun, wenn Sie keine View-Instanz haben? Zum Beispiel, wenn Sie derzeit keine Aktivität haben ...
Android-Entwickler
M ist das früheste Mal, dass Sie stabileInsetTop überprüfen können, und obwohl nur P unterstützte Kerben, würde ich lieber den tatsächlichen Einschub erhalten, anstatt auf die Standardeinstellung zurückzugreifen, wo ich kann. Diese Lösung funktioniert nicht, wenn Sie keine Aktivität haben.
James Jordan Taylor
Aha. Vielen Dank. Können Sie bitte ein "vollständigeres" Beispiel zeigen?
Android-Entwickler
Ich habe meine Antwort oben geändert, um die Methode in einem Beispiel zu verwenden.
James Jordan Taylor
Ich meinte ein funktionierendes Beispiel, aber ok.
Android-Entwickler
0

Kotlin-Version, die zwei beste Lösungen kombiniert

fun getStatusBarHeight(): Int {
    val resourceId = resources.getIdentifier("status_bar_height", "dimen", "android")
    return if (resourceId > 0) resources.getDimensionPixelSize(resourceId)
    else Rect().apply { window.decorView.getWindowVisibleDisplayFrame(this) }.top
}
  1. Nimmt status_bar_heightWert, wenn vorhanden
  2. Wenn status_bar_heightnicht vorhanden, wird die Höhe der Statusleiste aus dem Fensterdekor berechnet
Tomrozb
quelle