android - programacion - Altura de la barra de estado?
manual de programacion android pdf (10)
A partir de API 23 hay una mejor solución para obtener la altura de la barra de estado. La API 23 agrega una función WindowInsets
, por lo que puede usar este código para obtener el tamaño de las inserciones del sistema, en este caso en la parte superior.
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;
}
Tenga en cuenta que getRootWindowInsets()
devolverá null hasta que la vista se haya adjuntado a una ventana, por lo que no se puede usar directamente en onCreate()
pero puede agregar un detector para la ventana adjuntar y hacerlo allí. Aquí estoy agregando el Barra de estado insertada en el tamaño de mi barra de herramientas, que oculto y muestro, junto con la barra de estado. Cuando se muestra, quiero que la barra de estado sobre la parte superior de la misma, así que agregue la altura de la barra de estado al relleno superior de la barra de herramientas.
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) {
}
});
¿Hay alguna forma de obtener el alto de la barra de estado + barra de título? Verificando el foro dev muestra la misma pregunta pero no hay solución (que pueda encontrar).
Sé que podemos obtenerlo después del paso de diseño inicial, pero estoy buscando que aparezca en Crear () de mi actividad.
Gracias
Adjunte un ejecutable a una de sus vistas en su método onCreate, y coloque el código anterior allí. Esto hará que la aplicación calcule la barra de estado + la altura de la pantalla de títulos cuando estén conectados a la pantalla.
Eche un vistazo al código a continuación:
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;
}
});
Si esto todavía no funciona, intente invocar el método posDelayed de la vista en lugar de publicar y agregar un valor de milisegundos como segundo argumento.
Aunque esta es una pregunta antigua, descubrí que la respuesta no funcionaba en onCreate()
:
Encontré este código desde here que funciona en el método onCreate()
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
Espero que esto ayude a cualquiera que se encuentre con este problema.
Creo que la mejor forma de calcular eso es obtener la altura de la pantalla completa menos nuestro diseño principal
phoneBarsHeight = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getHeight()
- mainView.getHeight();
Y puedes ponerlo en onGlobalLayout()
. Esto también funciona en tabletas, lo probé en Theme.NoTitleBar, pero siempre debe funcionar.
Tal vez incluso pueda mejorarlo y usarlo en onCreate()
cambiando mainView.getHeight()
a mainView.getMeasuredHeight()
.
La forma admitida de obtener la altura de la barra de estado es usar la clase WindowInsets
partir de la API 21+:
customView.setOnApplyWindowInsetsListener((view, insets) -> {
// Handle insets
return insets.consumeSystemWindowInsets();
});
o WindowInsetsCompat
para bibliotecas de soporte:
ViewCompat.setOnApplyWindowInsetsListener(customView, (view, insets) -> {
// Handle insets
return insets.consumeSystemWindowInsets();
});
También puede anular el método onApplyWindowInsets
dentro de la vista:
public class CustomView extends View {
@Override
public WindowInsets onApplyWindowInsets(final WindowInsets insets) {
final int statusBarHeight = insets.getStableInsetTop();
return insets.consumeStableInsets();
}
}
Para más detalles, recomendaría consultar la charla de Chris Banes: convertirse en instalador maestro de ventanas (las diapositivas están disponibles here ).
La solución publicada por Jorgesys es muy buena, pero no funciona dentro del método Create (). Supongo que es porque la barra de estado y la barra de título se crean después de onCreate ().
La solución es fácil: debe poner código dentro de ejecutable y ejecutarlo después de onCreate () usando root.post((Runnable action) );
Entonces toda la solución:
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);
}
});
Lo encuentro here
Para aquellos, como yo, que quieren usarlo en sus diseños XML:
<...
android:layout_marginTop="@*android:dimen/status_bar_height"
... />
No se deje confundir por ese Android Studio (2.2 Preview 3 - al momento de escribir) no es compatible con esta noción. El tiempo de ejecución lo hace. Lo tomé del código fuente de Google.
Sugeriría el próximo código:
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;
}
Dos ejemplos:
1) Dispositivo 1 marca: Samsung, dispositivo: maguro, placa: atún, cpu_abi: armeabi-v7a, pantalla: ICL53F.M420KREL08, fabricante: Samsung, modelo: Galaxy Nexus, versión: 4.0.2, ver.sdk: 14 ;
Resolución de pantalla: 1280 x 720. No hay botones de hardware en este dispositivo.
Resultados:
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;
El dispositivo 1 tiene una barra de título en la parte superior de la pantalla y una barra de estado con botones de software en la parte inferior de la pantalla.
2) Dispositivo dispositivo 2: bravo, placa: bravo, cpu_abi: armeabi-v7a, pantalla: FRG83G, fabricante: HTC, modelo: HTC Desire, versión: 2.2.2, ver.sdk: 8,
Resolución de pantalla: 800 x 400. Este dispositivo tiene botones de hardware.
Resultados:
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;
El dispositivo 2 tiene una barra de título en la parte superior de la pantalla y no tiene ninguna barra de estado.
Dos soluciones fueron sugeridas arriba:
A) v.getTop() - rect.top
( es incorrecto para el dispositivo 1 - da 0 en lugar de 72)
B) display.getHeight() - v.getHeight()
( es incorrecto para el dispositivo 2 - da 0 en lugar de 38)
Variante:
display.getHeight() - v.getBottom() + rect.top
da resultados correctos en ambos casos.
Actualizar
3) Un ejemplo más (tercer dispositivo): marca: LGE, dispositivo: v909, cpu_abi: armeabi-v7a, pantalla: HMJ37, modelo: LG-V909, versión: 3.1, ver.sdk: 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
El dispositivo 3 tiene una orientación horizontal, no tiene una barra de título en la parte superior de la pantalla y tiene una barra de estado en la parte inferior de la pantalla.
Entonces, aquí:
int size_of_title_bar = rect.top;
int size_of_status_bar = display.getHeight() - v.getBottom();
Es correcto para los dispositivos 2 y 3. No estoy seguro sobre el dispositivo 1. El usuario me envió una captura de pantalla del dispositivo 1. Hay una barra de estado con el botón de software allí. Pero la expresión "display.getHeight () - v.getBottom ()" da 0.
También puede tomar la dimensión de la barra de estado que se encuentra en el archivo dimens.xml de Android utilizando la descripción de here .
Esto puede obtener el alto de la barra de estado sin la necesidad de esperar para dibujar.
Citando el código de la publicación del blog:
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
Necesitas poner este método en una clase ContextWrapper.
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);
Obtenga la Altura de la barra de estado en el método onCreate()
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;
}