Gibt es eine Möglichkeit, die Höhe der Statusleiste + Titelleiste zu ermitteln? Das Überprüfen des Entwicklerforums zeigt die gleiche Frage, aber keine Lösung (die ich finden konnte).
Ich weiß, dass wir es nach dem ersten Layout-Durchlauf erhalten können, aber ich möchte es in onCreate () meiner Aktivität erhalten.
Vielen Dank
Antworten:
Rect rectgle= new Rect(); Window window= getWindow(); window.getDecorView().getWindowVisibleDisplayFrame(rectgle); int StatusBarHeight= rectgle.top; int contentViewTop= window.findViewById(Window.ID_ANDROID_CONTENT).getTop(); int TitleBarHeight= contentViewTop - StatusBarHeight; Log.i("*** Jorgesys :: ", "StatusBar Height= " + StatusBarHeight + " , TitleBar Height = " + TitleBarHeight);
onCreate()
Verwenden Sie diese Methode, um die Höhe der Statusleiste für die Methode Ihrer Aktivität abzurufen:public int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = getResources().getDimensionPixelSize(resourceId); } return result; }
quelle
"?attr/actionBarSize"
Für diejenigen wie mich, die es in Ihren XML-Layouts verwenden möchten:
<... android:layout_marginTop="@*android:dimen/status_bar_height" ... />
Lassen Sie sich nicht verwirren, dass Android Studio (2.2 Vorschau 3 - zum Zeitpunkt des Schreibens) diesen Gedanken nicht unterstützt. Die Laufzeit tut. Ich habe es dem Quellcode von Google entnommen.
quelle
You must supply a layout_height(width) attribute
wenn Sie ihn für Layoutdateien verwenden.Obwohl dies eine alte Frage ist, stellte ich fest, dass die Antwort nicht funktionierte in
onCreate()
:Ich habe diesen Code von hier gefunden, der in der
onCreate()
Methode funktioniertpublic int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = getResources().getDimensionPixelSize(resourceId); } return result; }
Ich hoffe, dies hilft jedem, der auf dieses Problem stößt.
quelle
window
, daher war diese Funktion für mich nützlich!Die unterstützte Methode zum
WindowInsets
Abrufen der Statusleistenhöhe besteht darin, eine Klasse ab API 21+ zu verwenden:customView.setOnApplyWindowInsetsListener((view, insets) -> { // Handle insets return insets.consumeSystemWindowInsets(); });
oder
WindowInsetsCompat
für Support-Bibliotheken:ViewCompat.setOnApplyWindowInsetsListener(customView, (view, insets) -> { // Handle insets return insets.consumeSystemWindowInsets(); });
Sie können die
onApplyWindowInsets
Methode auch in der Ansicht überschreiben :public class CustomView extends View { @Override public WindowInsets onApplyWindowInsets(final WindowInsets insets) { final int statusBarHeight = insets.getStableInsetTop(); return insets.consumeStableInsets(); } }
Für weitere Details würde ich empfehlen, Chris Banes Vortrag zu überprüfen - Werden Sie ein Master-Fensterbauer (Folien hier verfügbar ).
quelle
Ich würde nächsten Code vorschlagen:
Rect rect = new Rect(); Window window = activity.getWindow(); if (window != null) { window.getDecorView().getWindowVisibleDisplayFrame(rect); android.view.View v = window.findViewById(Window.ID_ANDROID_CONTENT); android.view.Display display = ((android.view.WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); //return result title bar height return display.getHeight() - v.getBottom() + rect.top; }
Zwei Beispiele:
1) Gerät 1 Marke: Samsung, Gerät: Maguro, Board: Thunfisch, CPU_ABI: Armeabi-V7A, Anzeige: ICL53F.M420KREL08, Hersteller: Samsung, Modell: Galaxy Nexus, Version: 4.0.2, Version: 14 ;;
Bildschirmauflösung: 1280 x 720. Auf diesem Gerät befinden sich keine Hardwaretasten.
Ergebnisse:
rect: left=0 right=720 top=72 bottom=1208; v: left=0 right=720 top=72 bottom=1208; display: height=1208 width=720; correct result=72;
Gerät 1 verfügt über eine Titelleiste am oberen Bildschirmrand und eine Statusleiste mit Softwaretasten am unteren Bildschirmrand.
2) Gerät 2 Gerät: bravo, Board: bravo, cpu_abi: armeabi-v7a, Anzeige: FRG83G, Hersteller: HTC, Modell: HTC Desire, Version: 2.2.2, Version: 8,
Bildschirmauflösung: 800 x 400. Dieses Gerät verfügt über Hardwaretasten.
Ergebnisse:
rect: left=0 right=480 top=38 bottom=800; v: left=0 right=480 top=0 bottom=800; display: height=800 width=480; correct result: phone_bar_height=38;
Gerät 2 hat eine Titelleiste am oberen Bildschirmrand und überhaupt keine Statusleiste.
Oben wurden zwei Lösungen vorgeschlagen:
A) v.getTop() - rect.top
( es ist falsch für Gerät 1 - es gibt 0 statt 72)
B) display.getHeight() - v.getHeight()
( es ist falsch für Gerät 2 - es gibt 0 statt 38)
Variante:
display.getHeight() - v.getBottom() + rect.top
gibt in beiden Fällen korrekte Ergebnisse.
Aktualisieren
3) Ein weiteres Beispiel (drittes Gerät): Marke: LGE, Gerät: v909, cpu_abi: armeabi-v7a, Anzeige: HMJ37, Modell: LG-V909, Version: 3.1, Version: 12
rect: left=0 right=1280 top=0 bottom=720 v: left=0 right=1280 top=0 bottom=720 Display: height=768 width=1280 phone_bar_height=48
Gerät 3 hat eine horizontale Ausrichtung, keine Titelleiste am oberen Bildschirmrand und eine Statusleiste am unteren Bildschirmrand.
Also hier:
int size_of_title_bar = rect.top; int size_of_status_bar = display.getHeight() - v.getBottom();
Es ist für die Geräte 2 und 3 korrekt. Ich bin mir bei Gerät 1 nicht sicher. Der Benutzer hat mir einen Screenshot von Gerät 1 gesendet. Dort befindet sich eine Statusleiste mit der Softwaretaste. Der Ausdruck "display.getHeight () - v.getBottom ()" ergibt jedoch 0.
quelle
Sie können auch die Dimension der Statusleiste in der Datei dimension.xml von Android auf die in diesem Blogbeitrag beschriebene Weise übernehmen.
Dadurch kann die Höhe der Statusleiste ermittelt werden, ohne auf das Zeichnen warten zu müssen.
Zitieren des Codes aus dem Blog-Beitrag:
public int getStatusBarHeight() { int result = 0; int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = getResources().getDimensionPixelSize(resourceId); } return result; }
Sie müssen diese Methode in eine ContextWrapper-Klasse einfügen.
quelle
Hängen Sie eine ausführbare Datei an eine Ihrer Ansichten in Ihrer onCreate-Methode an und platzieren Sie den obigen Code dort. Dadurch berechnet die Anwendung die Statusleiste und die Höhe des Titelbildschirms, wenn sie an den Bildschirm angehängt werden.
Schauen Sie sich den folgenden Code an:
myView.post(new Runnable() { @Override public void run() { Rect rectgle= new Rect(); Window window= getWindow(); window.getDecorView().getWindowVisibleDisplayFrame(rectgle); int StatusBarHeight= rectgle.top; int contentViewTop= window.findViewById(Window.ID_ANDROID_CONTENT).getTop(); int TitleBarHeight= contentViewTop - StatusBarHeight; } });
Wenn dies immer noch nicht ausreicht, rufen Sie die postDelayed-Methode der Ansicht anstelle von post auf und fügen Sie als zweites Argument einen Millisekundenwert hinzu.
quelle
view
, auf dem Sie post () aufrufen, ist willkürlich korrekt? Egal welcheview
Sie verwenden,Runnable
wird in dieselbe UI-Thread-Nachrichtenwarteschlange gestellt? Ich weiß, dass es funktioniert, aber wird jemals irgendwo erklärt, dass diepost
ed runnable / message erst ausgeführt wird, nachdem dieview
s gemessen und layout () abgeschlossen wurden?Ich denke, ein besserer Weg, dies zu berechnen, besteht darin, die Höhe des Vollbilds abzüglich unseres Hauptlayouts zu ermitteln
Und du kannst es hineinstecken
onGlobalLayout()
. Dies funktioniert auch auf Tablets, ich habe es auf Theme.NoTitleBar versucht, aber es muss immer funktionieren.Vielleicht können Sie es sogar es verbessern und verwenden ,
onCreate()
indem SiemainView.getHeight()
aufmainView.getMeasuredHeight()
.quelle
Die von Jorgesys veröffentlichte Lösung ist sehr gut, funktioniert jedoch nicht in der onCreate () -Methode. Ich denke, das liegt daran, dass Statusleiste und Titelleiste nach onCreate () erstellt werden.
Die Lösung ist einfach: Sie sollten Code in runnable einfügen und ihn nach onCreate () mit using ausführen
root.post((Runnable action) );
Also die ganze Lösung:
root = (ViewGroup)findViewById(R.id.root); root.post(new Runnable() { public void run(){ Rect rectgle= new Rect(); Window window= getWindow(); window.getDecorView().getWindowVisibleDisplayFrame(rectgle); int StatusBarHeight= rectgle.top; int contentViewTop= window.findViewById(Window.ID_ANDROID_CONTENT).getTop(); int TitleBarHeight= contentViewTop - StatusBarHeight; Log.i("*** jakkubu :: ", "StatusBar Height= " + StatusBarHeight + " , TitleBar Height = " + TitleBarHeight); } });
Ich finde es hier
quelle
Ab API 23 gibt es eine bessere Lösung, um die Höhe der Statusleiste zu ermitteln. API 23 fügt eine
WindowInsets
Funktion hinzu, sodass Sie diesen Code verwenden können, um die Größe der Systemeinfügungen zu ermitteln, in diesem Fall oben.public int getStatusBarHeight() { if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { return binding.mainContent.getRootWindowInsets().getStableInsetTop(); } int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); if(resourceId != 0) { return getResources().getDimensionPixelSize(resourceId); } return 0; }
Beachten Sie, dass
getRootWindowInsets()
null zurückgegeben wird, bis die Ansicht an ein Fenster angehängt wurde, sodass sie nicht direkt in verwendet werdenonCreate()
kann. Sie können jedoch einen Listener für das Anhängen des Fensters hinzufügen und dort ausführen. Hier füge ich die Statusleiste der Größe hinzu meiner Symbolleiste, die ich ein- und ausblende, zusammen mit der Statusleiste. Wenn es angezeigt wird, möchte ich, dass die Statusleiste darüber angezeigt wird, sodass ich die Höhe der Statusleiste zum oberen Abstand der Symbolleiste hinzufüge.binding.mainContent.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View view) { binding.toolbar.setPadding(binding.toolbar.getPaddingLeft(), binding.toolbar.getPaddingTop() + getStatusBarHeight(), binding.toolbar.getPaddingRight(), binding.toolbar.getPaddingBottom()); binding.mainContent.removeOnAttachStateChangeListener(this); } @Override public void onViewDetachedFromWindow(View view) { } });
quelle
In Ordnung. Endgültige Antwort!!! Eine, die keine Nebenwirkungen hat, sich auf dokumentiertes Verhalten stützt, Q, Ausschnitte, Geräte mit unterschiedlicher Statusleistengröße je nach Ausrichtung usw. unterstützt.
protected void onCreate(Bundle savedInstanceState) { ... setContentView(R.layout.activity_main); .... // Use The topmost view of the activity, which // is guaranteed to be asked about window insets/ View rootView = findViewById(R.id.root_view_of_your_activity); ViewCompat.setOnApplyWindowInsetsListener(rootView, new OnApplyWindowInsetsListener() { @Override public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { //THIS is the value you want. statusBarHeight = insets.getSystemWindowInsetTop(); // Let the view handle insets as it likes. return ViewCompat.onApplyWindowInsets(v,insets); } });
Der Rückruf erfolgt nach onStart (), vor dem ersten Layout und gelegentlich danach.
quelle
Dies mag nicht miteinander zusammenhängen, aber in den meisten Fällen besteht der Grund dafür, dass Benutzer nach der Höhe der Statusleiste suchen, darin, ihre eigenen Ansichten zu versetzen, damit sie nicht darunter platziert werden.
Wenn
fitsSystemWindows
Sie die Ansicht festlegen, die Sie "nach unten drücken" möchten, um der Statusleiste Platz zu geben, erfolgt dies automatisch und entsprechend der Größe der Statusleiste auf jedem Gerät. Der Ansicht, für die diese Eigenschaft festgelegt ist, wird eine Auffüllung hinzugefügttrue
.Beachten Sie, dass das Auffüllen nur der ersten Ansicht in der Hierarchie mit der
fitSystemWindows
Einstellung auf hinzugefügt wirdtrue
Dies gilt beispielsweise für Fälle, in denen die Statusleiste durchscheinend ist. Stellen Sie sicher, dass Sie ein Thema für die Aktivität
fitSystemWindows
festlegen, die nicht festgelegt wurde. Andernfalls wird der Aktivität stattdessen der Abstand hinzugefügt (da er an erster Stelle in der Hierarchie steht).Dieser Artikel ist eine gute Lektüre zu diesem Thema
quelle