Hauteur de la barre d'état dans Android

332

Quelle est la hauteur de la barre d'état dans Android? Est-ce toujours la même chose?

D'après mes mesures, il semble que ce soit 25dp, mais je ne sais pas s'il a la même hauteur sur toutes les plateformes.

(Je veux savoir ceci pour implémenter correctement une transition de fondu d'une activité qui n'a pas de barre d'état à une qui en a)

hpique
la source
Si vous effectuez un fondu enchaîné, vous n'aurez pas besoin de connaître la hauteur de la barre d'état.
stealthcopter
2
J'en ai besoin parce que certains éléments sont centrés dans la mise en page, et je voudrais qu'ils se fondent les uns dans les autres.
hpique
doublon possible de Hauteur de la barre d'état?
molnarm

Réponses:

363

cette question a été répondue avant ... Hauteur de la barre d'état?

Mise à jour ::

Méthode actuelle:

ok, la hauteur de la barre d'état dépend de la taille de l'écran, par exemple dans un appareil avec une taille d'écran de 240 X 320 la hauteur de la barre d'état est de 20 pixels, pour un appareil avec une taille d'écran de 320 X 480 la hauteur de la barre d'état est de 25 pixels, pour un appareil avec 480 x 800 la hauteur de la barre d'état doit être de 38 px

donc je recommande d'utiliser ce script pour obtenir la hauteur de la barre d'état

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

(ancienne méthode) pour obtenir la hauteur de la barre d'état sur la onCreate()méthode de votre activité, utilisez cette méthode:

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
la source
Pas exactement. Je demande également si je peux supposer que la barre d'état a la même hauteur sur tous les appareils.
hpique
16
Ou utiliser dip? S'il a toujours 25dip, le code n'est pas nécessaire.
hpique
8
vous ne pouvez pas supposer que c'est toujours 25dp (vérifiez la hauteur par exemple sur le petit feu).
DallinDyer
1
Ne fonctionne pas dans runnable passé à view.post () dans onCreate () - return 0
Ixx
4
window.getDecorView().getWindowVisibleDisplayFrame(rectangle)n'est pas un moyen correct d'obtenir la hauteur de la barre d'état si vous êtes en mode multi-fenêtres + rotation portrait + deuxième fenêtre. Vous obtiendrez une valeur énorme (incluez la 1ère hauteur).
Tuan Chau
211

De tous les exemples de code que j'ai utilisés pour obtenir la hauteur de la barre d'état, le seul qui semble réellement fonctionner dans la onCreateméthode d'un Activityest le suivant:

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

Apparemment, la hauteur réelle de la barre d'état est conservée en tant que ressource Android. Le code ci-dessus peut être ajouté à une ContextWrapperclasse (par exemple un Activity).

Trouvé sur http://mrtn.me/blog/2012/03/17/get-the-height-of-the-status-bar-in-android/

Ben Clayton
la source
Au lieu de le coder en dur, mieux vaut le calculer dynamiquement. La méthode ci-dessus a fonctionné pour moi!
alchimiste
ne devriez-vous pas utiliser getDimension (...) à la place?
développeur Android
6
Un mot d'avertissement - cela ne fonctionne pas sur tous les appareils. Par exemple, sur le Transformer TF201 (ainsi que sur TF101, TF300 et certains autres appareils), la hauteur est signalée comme 25 lorsqu'il n'y a pas de barre d'état.
Błażej Czapp
4
Sur la base des commentaires ci-dessus, il me semble que le code vous dit quelle est la hauteur de la barre d'état sur un appareil particulier - pas ce qu'elle est sur une activité particulière (qui peut ne pas avoir de barre d'état).
hébété
en XML, la ressource dimen "@android: dimen / status_bar_height" peut être utilisée. <! - Hauteur de la barre d'état définie dans le fichier source du système Android -> <dimen name = "status_bar_height"> 24dp </dimen>. Mais vous ne pouvez pas le référencer directement dans votre projet d'application. Vous devez donc utiliser du code.
Tshunglee
48

Sur les périphériques MDPI, la barre d'état est de 25 pixels. Nous pouvons l'utiliser comme base et le multiplier par la densité (arrondie vers le haut) pour obtenir la hauteur de la barre d'état sur n'importe quel appareil:

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

Pour référence: ldpi = 0,75, mdpi = 1, hdpi = 1,5, xhdpi = 2

Grantland Chew
la source
6
C'est correct pour les appareils qui ont une barre d'état. Notez que puisque ce qui précède a été écrit, il est devenu vrai que tous les appareils n'en auront pas. Plus précisément, les appareils exécutant ICS peuvent avoir une barre d'état / de navigation combinée en bas et rien du tout en haut. Donc, dans ce cas, pour la plupart des fins de programmation, vous voudriez attribuer une hauteur de zéro à la barre d'état, mais la formulation ci-dessus vous donnerait une taille non nulle.
Carl
1
De plus, la valeur de 25 pixels n'est pas correcte pour tous les périphériques mdpi. Il peut varier en fonction du niveau de l'API. Par exemple, le dispositif d'émulation de tablette 10.1 WXGA rapporte 25 pixels aux API 16 et 19, mais 24 pixels aux API 24.
jk7
48

Coder en dur la taille ou utiliser la réflexion pour obtenir la valeur de status_bar_heightest considéré comme une mauvaise pratique. Chris Banes en a parlé au Droidcon New York . La méthode recommandée pour obtenir la taille de la barre d'état est via le OnApplyWindowInsetsListener :

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

Cela a été ajouté dans l'API 20 et est également rétroporté via ViewAppCompat .

Niklas
la source
Ceci est la réponse la plus précise aujourd'hui
Keith
pour moi, cela ne se déclenche qu'une seule fois, si j'ai des fragments via la navigation inférieure. Si je remplace à nouveau le fragment, cet écouteur ne sera pas appelé, y a-t-il également un getter compat?
urSus
74
Et pourtant, cette API est horrible, car le nombre de WTF / Gotchas dans les coulisses est énorme. Vous pensez que vous pouvez le faire avec n'importe quelle vue, mais non, vous devez remplacer certaines choses et vous assurer de transmettre les encarts à vos enfants (??) parce que CERTAINS ViewGroups le feront (conception matérielle) et TOUS LES AUTRES ne le feront pas ( disposition linéaire? ConstraintLayout? bonjour?). Au lieu que le système ait un Window.getStatusBarSize ()… nous devons NOUS ABONNER À UN ÉCOUTEUR FREAKING… rentrez chez vous Android, vous êtes ivre. Il suffit de coder en dur la taille jusqu'à ce que Google se réveille, nous sommes en 2018. J'espère que Chris Banes verra cela un jour…
Martin Marconcini
Dans mon cas, il n'est pas renvoyé. Je l'ai mis Activity # onCreated. Est-ce que j'ai fait quelque chose de mal? De plus, pourquoi n'utilisons-nous pas mView.getRootWindowInsets ()?
Adil Aliyev du
34

J'ai fusionné quelques solutions ensemble:

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

une autre alternative:

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

EDIT: Alternative à runJustBeforeBeingDrawn: https://stackoverflow.com/a/28136027/878126

développeur android
la source
getResources (). getDisplayMetrics (). heightPixels -getActivity (). findViewById (android.R.id.content) .getMeasuredHeight () ne fonctionne pas dans android lolipop
abbasalim
@ ArMo372 Réponse mise à jour. C'est juste que la vue doit d'abord passer la mesure. Vous n'avez pas besoin d'utiliser runJustBeforeBeingDrawn si vous l'avez déjà réussi. Vous ne l'utiliserez que sur des cas trop précoces.
développeur Android
28

Selon les directives de conception de Google ; la hauteur de la barre d'état est de 24 dp.

Si vous souhaitez obtenir la hauteur de la barre d'état en pixels, vous pouvez utiliser la méthode ci-dessous:

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

qui peut être appelé de l'activité avec:

statusBarHeight(getResources());
Rashid
la source
18
Jusqu'à Marshmallow c'était 25dp. Depuis Marshmallow, c'est 24dp.
Eugen Pechanec
1
il s'agit essentiellement de coder en dur la valeur - ce qui ne permet pas de modifications de conception
siliconeagle
1
et ne tient pas compte du fait que la barre d'état ne sera pas affichée dans les mêmes cas
jk7
19

La hauteur par défaut était de 25dp. Avec Android Marshmallow (API 23), la hauteur a été réduite à 24dp.

Mise à jour: veuillez noter que depuis l'âge des encoches et des caméras perforées, l'utilisation d'une hauteur statique pour la barre d'état ne fonctionne plus. Veuillez utiliser des encarts de fenêtre à la place!

crysxd
la source
1
doux! Je viens de créer un dimens.xml spécifiquement pour le niveau API 23+ où j'ai codé en dur la hauteur en 24dp.
Someone Somewhere
18

cela fonctionne également avec le lien de réfraction

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
la source
13

J'ai le même problème d'avoir à obtenir la hauteur de la barre d'état dans un onCreate. Cela fonctionne pour moi.

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;

À l'intérieur du 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;
}

Voir:

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

benhylau
la source
3
J'aime votre idée d'utiliser des valeurs basées sur la densité. Si vous allez utiliser le code à plusieurs endroits (ou utiliser d'autres valeurs liées à la densité), je préfère décharger le travail sur le système et stocker les valeurs dans une ressource dimen, ce qui rend le commutateur inutile. Vous devez créer un dossier et un fichier de ressources spécifiques à chaque dimension pour chaque densité. final Resources res = context.getResources (); int statusbarHeight = 0; essayez {statusbarHeight = res.getDimensionPixelSize (R.dimen.android_statusbar_height); } catch (NotFoundException e) {}
ProjectJourneyman
5
Le codage en dur de ces valeurs est dangereux, et si elles changent dans une version de plate-forme ultérieure?
David Snabel-Caunt
Je pense qu'au lieu d'utiliser des tailles de pixels codées en dur (une pour chaque densité), il vaut mieux utiliser "25dp".
développeur Android
13

La hauteur officielle est 24dp, comme indiqué officiellement par Google sur la page Web Android Design .

Joaquin Iurchuk
la source
12

Oui, lorsque je l'essaye avec View, il fournit le résultat de 25 pixels. Voici tout le 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
la source
Le code ci-dessus fonctionne pour moi lorsque je crée une nouvelle disposition linéaire comme vous l'avez fait ci-dessus, mais quand je trouve findviewbyid pour le lySpin à partir du xml. puis il retourne null. ne le comprenant pas, il se comporte ainsi.
Shaista Naaz
Parce que la mise en page ne connaît pas encore sa taille dans onCreate car elle n'a pas fini d'être dessinée. Ce que je fais habituellement, c'est publier un Runnable sur le thread d'interface utilisateur de onCreate qui donne le temps à l'interface utilisateur de se dessiner.
Jason Robinson
8

240x320 - 20px

320x480 - 25px

480x800 + - 38px

Denis
la source
3
Ce n'est plus exact. Utilisez une méthode de mesure de la barre d'état.
Michael
7

Essaye ça:

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

cela n'a pas fonctionné pour moi dans la méthode onCreate pour l'activité, mais l'a fait quand je l'ai mis dans un onClickListener et m'a donné une mesure de 25

Martyn
la source
Je soupçonne qu'au moment où il a testé dans onCreate (), la barre d'état n'avait pas encore été créée. En revanche, lorsqu'il a cliqué manuellement pour activer son code onClickListener (), la barre avait déjà eu beaucoup de temps de réflexion pour s'afficher, et il a pu récupérer sa taille.
Carl
6

la hauteur de la barre d'état est de 24dp dans 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>

vous pouvez trouver la réponse dans le code source: frameworks \ base \ core \ res \ res \ values ​​\ dimens.xml

xiaoyuan hu
la source
existe-t-il un moyen d'obtenir cette ressource dans nos XML? @android:dimen/status_bar_heightne fonctionne pas pour moi
Patrick
4

Pour résoudre ce problème, j'ai utilisé une approche combinée. Cela est nécessaire car sur les tablettes, la barre système soustrait déjà ses pixels lorsque display.getHeight () est appelé. Je vérifie donc d'abord si une barre système est présente, puis l'approche de Ben Claytons, qui fonctionne bien sur les téléphones.

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
la source
3

Grâce à @Niklas +1, c'est la bonne façon de procéder.

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

Veuillez m'excuser si le code n'est pas correct à 100%, converti à partir de Xamarin C # mais c'est juste. Fonctionne avec des encoches, etc.

Pierre
la source
2

Solution plein écran basculée:

Cette solution peut ressembler à une solution de contournement, mais elle explique en fait si votre application est en plein écran (aka masquer la barre d'état) ou non:

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

De cette façon, si votre application est actuellement en plein écran, elle barheightsera égale à 0.

Personnellement, j'ai dû utiliser cela pour corriger les coordonnées absolues de TouchEvent pour tenir compte de la barre d'état comme suit:

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

Et cela obtiendra la coordonnée absolue absolue, que l'application soit en plein écran ou non.

Prendre plaisir

Aaron Gillion
la source
Merci, c'était la seule solution qui a fonctionné pour moi lorsque le clavier Android s'affiche également.
Thiago Moura
2

Sur Android 4.1 et supérieur, vous pouvez définir le contenu de votre application pour qu'il apparaisse derrière la barre d'état, afin que le contenu ne se redimensionne pas lorsque la barre d'état se cache et s'affiche. Pour ce faire, utilisez SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN. Vous devrez peut-être également utiliser SYSTEM_UI_FLAG_LAYOUT_STABLE pour aider votre application à conserver une mise en page stable.

Lorsque vous utilisez cette approche, il devient de votre responsabilité de vous assurer que les parties critiques de l'interface utilisateur de votre application (par exemple, les contrôles intégrés dans une application Maps) ne finissent pas par être couvertes par des barres système. Cela pourrait rendre votre application inutilisable. Dans la plupart des cas, vous pouvez gérer cela en ajoutant l'attribut android: fitsSystemWindows à votre fichier de disposition XML, défini sur true. Cela ajuste le remplissage du ViewGroup parent pour laisser de l'espace aux fenêtres système. C'est suffisant pour la plupart des applications.

Dans certains cas, cependant, vous devrez peut-être modifier le remplissage par défaut pour obtenir la mise en page souhaitée pour votre application. Pour manipuler directement la présentation de votre contenu par rapport aux barres système (qui occupent un espace connu sous le nom de "insertions de contenu" de la fenêtre), remplacez fitSystemWindows (insertions rect). La méthode fitSystemWindows () est appelée par la hiérarchie des vues lorsque les encarts de contenu d'une fenêtre ont changé, pour permettre à la fenêtre d'ajuster son contenu en conséquence. En remplaçant cette méthode, vous pouvez gérer les encarts (et donc la disposition de votre application) comme vous le souhaitez.

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

xiaoyuan hu
la source
1

Si vous connaissez exactement la taille VS hauteur

comme

par exemple, dans un appareil avec une taille d'écran de 320 X 480, la hauteur de la barre d'état est de 25 pixels, pour un appareil avec 480 x 800, la hauteur de la barre d'état doit être de 38 pixels.

alors vous pouvez simplement obtenir la largeur de votre vue / la taille de l'écran, vous pouvez simplement utiliser une instruction if else pour obtenir la hauteur de la barre d'état

Steven Shih
la source
D'après mon expérience, la hauteur semble être basée sur la densité plutôt que sur la taille de l'écran. Bien sûr, la densité elle-même est généralement liée à la taille de l'écran, il existe donc une relation indirecte. Mon ancien Moto Droid, par exemple, a un écran 480x854 (plutôt que 480x800), et la barre d'état est également haute de 38 pixels.
Carl
Ils ont inventé le dp pour cela (pixels indépendants de la densité)
Roel
1

La raison pour laquelle la première réponse ne fonctionne pas pour certaines personnes est que vous ne pouvez pas obtenir les dimensions d'une vue tant qu'elle n'est pas prête à être rendue. Utilisez un OnGlobalLayoutListenerpour obtenir ces dimensions lorsque vous pouvez réellement:

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

Il s'agit de la méthode la plus fiable.

user1112789
la source
1
@androiddeveloper OnGlobal! = GlobalOn
marijnz0r
@ marijnz0r C'est bizarre. Quel est le problème avec ça?
développeur Android
@androiddeveloper Je ne sais pas, mais je pensais la même chose que vous il y a quelques jours. Voir: stackoverflow.com/a/19216041/4587214
marijnz0r
@ marijnz0r Donc, les deux font la même chose. Cela me rappelle d'autres cas où ils ont donné un nouveau nom à une substance qui existait déjà et qui a rendu obsolète la précédente. Exemple "fill_parent" vs "match_parent": developer.android.com/reference/android/view/…
développeur Android
1

Étant donné que le mode multi-fenêtres est maintenant disponible, votre application peut ne pas avoir de barre d'état en haut.

La solution suivante gère automatiquement tous les cas pour vous.

android:fitsSystemWindows="true"

ou par programme

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

vous pouvez également obtenir une vue racine par

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

Pour plus de détails sur l'obtention de la vue racine, consultez - https://stackoverflow.com/a/4488149/9640177

mayank1513
la source
0

Ce problème est récemment devenu pertinent pour moi en raison de l'encoche de mon Pixel 3XL. J'ai vraiment aimé la solution du développeur Android , mais je voulais pouvoir obtenir la hauteur de la barre d'état à volonté, car elle était spécifiquement nécessaire pour une animation plein écran que je devais jouer. La fonction ci-dessous a permis une requête fiable:

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

Et puis dans la classe d'activité:

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

Vous voudrez bien sûr faire passer une référence faible de l'activité au paramètre de méthode de la classe Helper statique, mais par souci de concision, je me suis abstenu dans cet exemple. Les blurBitmapet errorHudFrameLayoutsont omis pour la même raison, car ils ne concernent pas directement l'obtention de la hauteur de la barre d'état.

James Jordan Taylor
la source
Si c'est pour Android P et supérieur, pourquoi vérifier avec Android M? De plus, que feriez-vous si vous n'avez pas d'instance View? Par exemple, si vous n'avez pas d'activité actuellement ...
développeur Android
M est le plus ancien que vous puissiez vérifier stableInsetTop, et même si seules les encoches prises en charge par P, je préfère obtenir l'encart réel au lieu de retomber à la valeur par défaut où je peux. Cette solution ne fonctionne pas si vous n'avez pas d'activité.
James Jordan Taylor
Je vois. Je vous remercie. Pouvez-vous s'il vous plaît montrer un exemple plus "complet"?
développeur Android
J'ai changé ma réponse ci-dessus pour utiliser la méthode dans un exemple.
James Jordan Taylor
0

Version Kotlin qui combine deux meilleures solutions

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. Prend de la status_bar_heightvaleur si elle est présente
  2. Si status_bar_heightn'est pas présent, calcule la hauteur de la barre d'état à partir du décor de fenêtre
tomrozb
la source