Altura de la barra de estado en Android

332

¿Cuál es la altura de la barra de estado en Android? ¿Es siempre lo mismo?

Según mis mediciones, parece que son 25dp, pero no estoy seguro de si tiene la misma altura en todas las plataformas.

(Quiero saber esto para implementar correctamente una transición de desvanecimiento de una actividad que no tiene barra de estado a una que sí la tenga)

hpique
fuente
Si realiza un fundido cruzado, no necesitará saber la altura de la barra de estado.
stealthcopter
2
Lo necesito porque algunos elementos están centrados en el diseño, y me gustaría que se desvanezcan entre sí.
hpique
posible duplicado de Altura de la barra de estado?
molnarm

Respuestas:

363

esta pregunta fue respondida antes ... Altura de la barra de estado?

Actualización ::

Método actual:

ok, la altura de la barra de estado depende del tamaño de la pantalla, por ejemplo, en un dispositivo con un tamaño de pantalla de 240 X 320, la altura de la barra de estado es de 20 px, para un dispositivo con un tamaño de pantalla de 320 X 480, la altura de la barra de estado es de 25 px, para un dispositivo con 480 x 800, la altura de la barra de estado debe ser de 38 px

así que recomiendo usar este script para obtener la altura de la barra de estado

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

(Método antiguo) para obtener la Altura de la barra de estado en el onCreate()método de su Actividad, use este método:

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
fuente
No exactamente. También pregunto si puedo asumir que la barra de estado tiene la misma altura en todos los dispositivos.
hpique
16
¿O usar dip? Si siempre tiene 25dip, entonces el código no es necesario.
hpique
8
no puedes asumir que siempre es de 25dp (mira la altura, por ejemplo, en el Kindle Fire).
DallinDyer
1
No funciona en runnable pasado a view.post () en onCreate () - return 0
Ixx
44
window.getDecorView().getWindowVisibleDisplayFrame(rectangle)no es una forma correcta de obtener la altura de la barra de estado si está en modo de ventanas múltiples + rotación vertical + segunda ventana. Obtendrá un gran valor (incluya la primera altura).
Tuan Chau
211

De todos los ejemplos de código que he usado para obtener la altura de la barra de estado, el único que realmente parece funcionar en el onCreatemétodo de un Activityes este:

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

Aparentemente, la altura real de la barra de estado se mantiene como un recurso de Android. El código anterior se puede agregar a una ContextWrapperclase (por ejemplo, an Activity).

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

Ben Clayton
fuente
En lugar de codificarlo, es mejor calcularlo dinámicamente. ¡El método anterior funcionó para mí!
alquimista
¿no deberías usar getDimension (...) en su lugar?
Desarrollador de Android
66
Una advertencia: esto no funciona en todos los dispositivos. Por ejemplo, en Transformer TF201 (así como TF101, TF300 y algunos otros dispositivos), la altura se informa como 25 donde no hay barra de estado.
Błażej Czapp
44
Según los comentarios anteriores, me parece que el código le dice cuál es la altura de la barra de estado en un dispositivo en particular, no cuál es en una actividad en particular (que en realidad puede no tener una barra de estado).
aturdido el
en XML se puede utilizar el recurso dimen "@android: dimen / status_bar_height". <! - Altura de la barra de estado definida en el archivo fuente del sistema Android -> <dimen name = "status_bar_height"> 24dp </dimen>. Pero no puede hacer referencia directa en su proyecto de aplicación. Entonces debes usar el código.
Tshunglee
48

En dispositivos MDPI, la barra de estado es de 25 px. Podemos usar esto como base y multiplicarlo por la densidad (redondeada) para obtener la altura de la barra de estado en cualquier dispositivo:

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

Para referencia: ldpi = .75, mdpi = 1, hdpi = 1.5, xhdpi = 2

Grantland Chew
fuente
66
Esto es correcto para dispositivos que tienen una barra de estado. Tenga en cuenta que desde que se escribió lo anterior, se hizo realidad que no todos los dispositivos tendrán uno. Específicamente, los dispositivos que ejecutan ICS pueden tener una barra de estado / navegación combinada en la parte inferior y nada en la parte superior. Entonces, para ese caso, para la mayoría de los propósitos de programación, desearía asignar una altura de cero a la barra de estado, pero la formulación anterior le daría un tamaño distinto de cero.
Carl
1
Además, el valor de 25 px no es correcto para todos los dispositivos mdpi. Puede variar según el nivel de API. Por ejemplo, el dispositivo emulador de tableta WXGA 10.1 informa 25 px en API 16 y 19, pero 24 px en API 24.
jk7
48

Codificar el tamaño o usar la reflexión para obtener el valor de status_bar_heightse considera una mala práctica. Chris Banes habló sobre esto en el Droidcon New York . La forma recomendada de obtener el tamaño de la barra de estado es a través de OnApplyWindowInsetsListener :

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

Esto se agregó en API 20 y también se respalda a través de ViewAppCompat .

Niklas
fuente
Esta es la respuesta más precisa hoy
keith
para mí esto solo se dispara una vez, si tengo fragmentos a través del navegador inferior. Si vuelvo a reemplazar el fragmento, no se llama a este oyente, ¿hay también un get get compatible?
urSus
74
Y sin embargo, esta API es horrible, porque la cantidad de WTF / Gotchas detrás de escena es enorme. Pensaría que puede hacerlo con cualquier vista, pero no, necesita anular ciertas cosas y asegurarse de que USTED pase las inserciones a sus hijos (??) porque ALGUNOS ViewGroups lo harán (diseño de material) y TODOS LOS OTROS no lo harán ( diseño lineal? RestricciónDisposición? hola?). En lugar de que el sistema tenga un Window.getStatusBarSize () ... tenemos que SUSCRIBIRME A UN ESCUCHADOR FALTANTE ... ve a Android, estás borracho. Simplemente codifique el tamaño hasta que Google se despierte, estamos en 2018. Espero que Chris Banes vea esto algún día ...
Martin Marconcini
En mi caso no está siendo despedido. Lo puse Actividad # en Creado. ¿Hice algo mal? Además, ¿por qué no usamos mView.getRootWindowInsets ()?
Adil Aliyev
34

He fusionado algunas soluciones juntas:

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

otra alternativa:

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

EDITAR: alternativa a runJustBeforeBeingDrawn: https://stackoverflow.com/a/28136027/878126

desarrollador de Android
fuente
getResources (). getDisplayMetrics (). heightPixels -getActivity (). findViewById (android.R.id.content) .getMeasuredHeight () no funciona en android lolipop
abbasalim
@ ArMo372 Respuesta actualizada. Es solo que la vista necesita pasar la medida primero. No necesita usar runJustBeforeBeingDrawn si ya lo pasó. Lo usará solo en casos demasiado tempranos.
Desarrollador de Android
28

De acuerdo con las pautas de diseño de Google ; La altura de la barra de estado es de 24 dp.

Si desea obtener la altura de la barra de estado en píxeles, puede usar el siguiente método:

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

que se puede llamar desde la actividad con:

statusBarHeight(getResources());
Rashid
fuente
18
Hasta Marshmallow era de 25dp. Desde Marshmallow es de 24dp.
Eugen Pechanec
1
esto es esencialmente codificar el valor, lo que no permite cambios de diseño
siliconaagle
1
y no tiene en cuenta el hecho de que la barra de estado no se mostrará en los mismos casos
jk7
19

La altura predeterminada solía ser 25dp. Con Android Marshmallow (API 23) la altura se redujo a 24dp.

Actualización: Tenga en cuenta que desde que comenzó la era de las muescas y las cámaras de perforación completa, el uso de una altura estática para la barra de estado ya no funciona. Por favor, use inserciones de ventana en su lugar!

crysxd
fuente
1
¡dulce! Acabo de crear un dimens.xml específicamente para el nivel API 23+ donde he codificado la altura como 24dp.
Alguien en alguna parte
18

esto también funciona con la referencia enlace de

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

Tengo el mismo problema de tener que obtener la altura de la barra de estado en un onCreate. Esto funciona para mi.

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;

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

Ver:

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

benhylau
fuente
3
Me gusta tu idea de usar valores basados ​​en la densidad. Si va a usar el código en varios lugares (o usar otros valores relacionados con la densidad), prefiero descargar el trabajo al sistema y almacenar los valores en un recurso de dimen, lo que hace innecesario el cambio. Es necesario crear una carpeta de dimensiones específicas y un archivo de recursos para cada densidad. Recursos finales res = context.getResources (); int statusbarHeight = 0; pruebe {statusbarHeight = res.getDimensionPixelSize (R.dimen.android_statusbar_height); } catch (NotFoundException e) {}
ProjectJourneyman
55
Codificar estos valores es peligroso, ¿y si cambian en una versión de plataforma posterior?
David Snabel-Caunt
Creo que en lugar de usar tamaños de píxeles codificados (uno para cada densidad), es mejor usar "25dp".
Desarrollador de Android
12

Sí, cuando lo pruebo con View, proporciona el resultado de 25px. Aquí está el código completo:

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
fuente
El código anterior funciona para mí cuando creo un nuevo diseño lineal como lo hizo anteriormente, pero cuando encuentro viewbybyid para el lySpin desde el xml. entonces vuelve nulo. sin entender y se está comportando así.
Shaista Naaz
Porque el diseño aún no conoce su tamaño en onCreate porque no ha terminado de dibujarse. Lo que generalmente hago es publicar un Runnable en el hilo de la interfaz de usuario de onCreate, lo que le da tiempo a la interfaz de usuario para dibujarse.
Jason Robinson
8

240x320 - 20px

320x480 - 25px

480x800 + - 38px

Denis
fuente
3
Esto ya no es exacto. Use un método para medir la barra de estado.
Michael
7

Prueba esto:

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

no funcionó para mí en el método onCreate para la actividad, pero funcionó cuando lo puse en un onClickListener y me dio una medida de 25

Martyn
fuente
Sospecho que en el momento en que lo probó en onCreate (), la barra de estado aún no se había creado. Por el contrario, cuando hizo clic manualmente para activar su código onClickListener (), la barra ya había tenido mucho tiempo para pensar, y pudo recuperar su tamaño.
Carl
6

la altura de la barra de estado es de 24dp en 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>

puede encontrar la respuesta en el código fuente: frameworks \ base \ core \ res \ res \ values ​​\ dimens.xml

Xiaoyuan hu
fuente
¿Hay alguna manera de obtener este recurso en nuestros XML? @android:dimen/status_bar_heightno funciona para mí
Patrick
4

Para resolver esto, utilicé un enfoque combinado. Esto es necesario ya que en las tabletas la barra del sistema ya resta sus píxeles cuando se llama a display.getHeight (). Así que primero verifico si hay una barra del sistema, y ​​luego el enfoque de Ben Clayton, que funciona bien en los teléfonos.

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

Gracias a @Niklas +1 esta es la forma correcta de hacerlo.

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

Por favor, discúlpeme si el código no es 100% correcto, lo convirtió de Xamarin C #, pero esto es justo. Funciona con muescas, etc.

Pierre
fuente
2

Solución de pantalla completa conmutada:

Esta solución puede parecer una solución alternativa, pero en realidad explica si su aplicación es de pantalla completa (también conocida como ocultar la barra de estado) o no:

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

De esta manera, si su aplicación está actualmente en pantalla completa, barheightserá igual a 0.

Personalmente, tuve que usar esto para corregir las coordenadas absolutas de TouchEvent para tener en cuenta la barra de estado de la siguiente manera:

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

Y eso obtendrá la coordenada y absoluta, ya sea que la aplicación sea de pantalla completa o no.

Disfrutar

Aaron Gillion
fuente
Gracias, esta fue la única solución que funcionó para mí cuando también se muestra el teclado de Android.
Thiago Moura
2

En Android 4.1 y versiones posteriores, puede configurar el contenido de su aplicación para que aparezca detrás de la barra de estado, de modo que el contenido no cambie de tamaño a medida que la barra de estado se oculta y muestra. Para hacer esto, use SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN. Es posible que también deba usar SYSTEM_UI_FLAG_LAYOUT_STABLE para ayudar a que su aplicación mantenga un diseño estable.

Cuando utiliza este enfoque, se convierte en su responsabilidad asegurarse de que las partes críticas de la interfaz de usuario de su aplicación (por ejemplo, los controles integrados en una aplicación de Mapas) no terminen siendo cubiertas por las barras del sistema. Esto podría hacer que su aplicación sea inutilizable. En la mayoría de los casos, puede manejar esto agregando el atributo android: fitsSystemWindows a su archivo de diseño XML, establecido en verdadero. Esto ajusta el relleno del ViewGroup primario para dejar espacio para las ventanas del sistema. Esto es suficiente para la mayoría de las aplicaciones.

Sin embargo, en algunos casos, es posible que deba modificar el relleno predeterminado para obtener el diseño deseado para su aplicación. Para manipular directamente cómo se presenta su contenido en relación con las barras del sistema (que ocupan un espacio conocido como "insertos de contenido" de la ventana), anule fitSystemWindows (insertos Rect). La jerarquía de vistas llama al método fitSystemWindows () cuando las inserciones de contenido de una ventana han cambiado, para permitir que la ventana ajuste su contenido en consecuencia. Al anular este método, puede manejar las inserciones (y, por lo tanto, el diseño de su aplicación) como desee.

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

Xiaoyuan hu
fuente
1

Si sabes exactamente el tamaño VS altura

me gusta

por ejemplo, en un dispositivo con un tamaño de pantalla de 320 X 480, la altura de la barra de estado es de 25 px, para un dispositivo con 480 x 800 la altura de la barra de estado debe ser de 38 px

entonces puede obtener el ancho de su vista / el tamaño de la pantalla, puede usar una instrucción if else para obtener la altura de la barra de estado

Steven Shih
fuente
En mi experiencia, la altura parece estar basada en la densidad en lugar del tamaño de la pantalla. Por supuesto, la densidad en sí está típicamente relacionada con el tamaño de la pantalla, por lo que existe una relación indirecta. Mi viejo Moto Droid, por ejemplo, tiene una pantalla de 480x854 (en lugar de 480x800), y la barra de estado también tiene 38 píxeles de alto.
Carl
Inventaron dp para esto (píxeles independientes de la densidad)
Roel
1

La razón por la cual la respuesta principal no funciona para algunas personas es porque no puede obtener las dimensiones de una vista hasta que esté lista para renderizarse. Use un OnGlobalLayoutListenerpara obtener dichas dimensiones cuando realmente pueda:

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

Este es el método más confiable.

usuario1112789
fuente
1
@androiddeveloper OnGlobal! = GlobalOn
marijnz0r
@ marijnz0r Qué extraño. ¿Cuál es el problema con eso?
Desarrollador de Android
@androiddeveloper No lo sé, pero también pensé lo mismo que tú hace unos días. Ver: stackoverflow.com/a/19216041/4587214
marijnz0r
@ marijnz0r Entonces ambos hacen lo mismo. Me recuerda a otros casos que dieron un nuevo nombre a un material que ya existía y desaprobaron el anterior. Ejemplo "fill_parent" vs "match_parent": developer.android.com/reference/android/view/…
desarrollador de Android
1

Dado que el modo de ventanas múltiples está disponible ahora, es posible que su aplicación no tenga la barra de estado en la parte superior.

La siguiente solución maneja todos los casos automáticamente por usted.

android:fitsSystemWindows="true"

o programáticamente

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

También puede obtener vista de raíz por

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

Para obtener más detalles sobre cómo obtener la vista raíz, consulte: https://stackoverflow.com/a/4488149/9640177

mayank1513
fuente
0

Este problema recientemente se volvió relevante para mí debido a la muesca en mi Pixel 3XL. Realmente me gustó la solución de desarrollador de Android , pero quería poder obtener la altura de la barra de estado a voluntad, ya que era específicamente necesario para una animación de pantalla completa que necesitaba jugar. La siguiente función permitió una consulta confiable:

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

Y luego en la clase de actividad:

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

Por supuesto, querrá hacer pasar una referencia débil de la actividad al parámetro del método de la clase Helper estática, pero por razones de brevedad me abstuve en este ejemplo. Los blurBitmapy errorHudFrameLayoutse omiten por el mismo motivo, ya que no pertenecen directamente a la obtención de la altura de la barra de estado.

James Jordan Taylor
fuente
Si es para Android P y superior, ¿por qué consultar con Android M? Además, ¿qué haría si no tiene una instancia de View? Por ejemplo, si no tiene una actividad actualmente ...
desarrollador de Android
M es lo más temprano que puede verificar stableInsetTop, y aunque solo P admite muescas, prefiero obtener el recuadro real en lugar de volver al valor predeterminado donde puedo. Esta solución no funciona si no tienes una actividad.
James Jordan Taylor
Veo. Gracias. ¿Puedes mostrar un ejemplo más "completo"?
Desarrollador de Android
Cambié mi respuesta anterior para usar el método en un ejemplo.
James Jordan Taylor
0

Versión de Kotlin que combina dos mejores soluciones.

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. Toma status_bar_height valor si está presente
  2. Si status_bar_heightno está presente, calcula la altura de la barra de estado a partir de la decoración de la ventana
tomrozb
fuente