¿Cómo obtener la altura de ActionBar?

190

Estoy tratando de obtener la altura de ActionBar(usando Sherlock) cada vez que se crea una actividad (especialmente para manejar los cambios de configuración en la rotación donde la altura de ActionBar podría cambiar).

Para esto utilizo el método ActionBar.getHeight()que funciona solo cuando ActionBarse muestra.

Cuando se crea la primera actividad por primera vez, puedo llamar getHeight()a la onCreateOptionsMenudevolución de llamada. Pero este método no se llama después.

Entonces, mi pregunta es cuándo puedo llamar a getHeight () y estar seguro de que no devuelve 0. O si no es posible, ¿cómo puedo configurar la altura de la barra de acciones?

znat
fuente

Respuestas:

419

Si bien la respuesta de @ birdy es una opción si desea controlar explícitamente el tamaño de ActionBar, hay una manera de extraerlo sin bloquear el tamaño que encontré en la documentación de soporte. Es un poco incómodo, pero funcionó para mí. Necesitará un contexto, este ejemplo sería válido en una Actividad.

// Calculate ActionBar height
TypedValue tv = new TypedValue();
if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
{
    Int actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}

Kotlin :

val tv = TypedValue()
if (requireActivity().theme.resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
    val actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, resources.displayMetrics)
}
Antonio
fuente
13
gran ayuda !! pero desde donde encuentras todas esas cosas !!
vikky
55
En general, de Google exhaustivo o drudging a través del manual del desarrollador. Creo que esto último en este caso, pero ha pasado un tiempo.
Anthony
1
¿Podemos cambiar el tamaño de la barra de acción solo para una actividad en particular?
Sudarshan Bhat
Esto funcionó para mí en ambos casos: (i) onCreateView y (ii) onConfigurationChanged. ¡Gracias!
Marcelo Noguti
55
"android.R.attr.actionBarSize" no funciona en la versión 2.3 de Android, pero "R.attr.actionBarSize" funciona en todas las versiones de Android. simplemente use "R.attr.actionBarSize" en lugar de "android.R.attr.actionBarSize", "android.support.v7.appcompat.R.attr.actionBarSize" y etc.
Nathaniel Jobs
148

En XML, debe usar este atributo:

android:paddingTop="?android:attr/actionBarSize"
cesards
fuente
20
en caso de que esté utilizando ActionBarCompat "@ dimen / abc_action_bar_default_height"
Ali AlNoaimi
10
Gracias Ali AlNoaimi! Con AppCompat v21, el nombre ha cambiado a: "@ dimen / abc_action_bar_default_height_material"
Tony Ceralva
55
Como @muzikant menciona a continuación, para appcompat, si desea usarlo en el código, el atributo correcto es android.support.v7.appcompat.R.attr.actionBarSize. Si desea utilizarlo en xml diseño, android:paddingTop="?attr/actionBarSize". Funciona bien en todas partes.
rpattabi
1
Esta solución es maravillosa cuando está utilizando un marco XML personalizado.
tryp
2
Si quiero usar este atributo pero negativo para usarlo con un relleno negativo. ¿Cómo puedo hacer eso?
Desarrollador de Tiger
17

Ok, busqué en Google y llegué a esta publicación varias veces, así que creo que será bueno que me describan no solo para Sherlock sino también para appcompat:

Altura de la barra de acción con appCompat

Bastante similar a la descripción de @Anthony, puede encontrarlo con el siguiente código (acabo de cambiar la identificación del recurso):

TypedValue tv = new TypedValue();

if (getActivity().getTheme().resolveAttribute(R.attr.actionBarSize, tv, true))
{
    int actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
}

Problema Pre Sandwitch

Necesitaba la altura de la barra de acción porque en dispositivos pre ICE_CREAM_SANDWITCH mi vista se superponía a la barra de acción. Intenté configurar android: layout_marginTop = "? Android: attr / actionBarSize", android: layout_marginTop = "? Attr / actionBarSize", configurando la superposición desactivada para ver / barra de acción e incluso altura de barra de acción fija con tema personalizado pero nada funcionó. Así se veía:

problema de superposición

Desafortunadamente, descubrí que con el método descrito anteriormente obtengo solo la mitad de la altura (supongo que la barra de opciones no está en su lugar), así que para solucionar completamente el problema, necesito duplicar la altura de la barra de acción y todo parece estar bien:

solapamiento fijo

Si alguien conoce una mejor solución (que doblar actionBarHeight), me alegrará avisarme cuando vengo del desarrollo de iOS y encontré que la mayoría de las cosas de la vista de Android son bastante confusas :)

Saludos,

hris.to

hris.to
fuente
Experimenté lo mismo al usar pestañas. El problema es que a veces es difícil detectar pestañas versus no pestañas, ya que algunos dispositivos colapsan visualmente las pestañas en la barra de acciones base en algunas situaciones. Entonces, lo que funcionó para mí es justo ActionBar.getHeight(). Dependiendo de la situación, eso también puede funcionar para usted.
TalkLittle
Estaba enfrentando el problema porque solo estaba considerando la altura de la barra de acción, luego agregué también la altura de la 'barra de notificaciones'. Funciono bien para mi.
Darpan
¿Usas FrameLayout y tienes layout_gravity="center_vertical"? Cámbialo a "bottom". Android 2.3 maneja el margen en FrameLaoyut de manera diferente a los androides más nuevos.
Oliv
16

La respuesta @Anthony funciona para dispositivos que admiten ActionBary para aquellos dispositivos que solo admiten el Sherlock Action Barsiguiente método

    TypedValue tv = new TypedValue();
    if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());

    if(actionBarHeight ==0 && getTheme().resolveAttribute(com.actionbarsherlock.R.attr.actionBarSize, tv, true)){
            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
    }

   //OR as stated by @Marina.Eariel
   TypedValue tv = new TypedValue();
   if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){
      if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
   }else if(getTheme().resolveAttribute(com.actionbarsherlock.R.attr.actionBarSize, tv, true){
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,getResources().getDisplayMetrics());
   }
laaptu
fuente
Puede ajustar el primero si con "if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.HONEYCOMB) {}" para evitar errores de tiempo de ejecución en versiones anteriores de Android.
Marina.Eariel
Para mí, com.actionbarsherlock.R.attr.actionBarSizetrabajé para Android 2.3 y 4.0, por lo que parece que puedes usar esto independientemente de la versión de Android.
Felix
13

Creo que la forma más segura sería:

private int getActionBarHeight() {
    int actionBarHeight = getSupportActionBar().getHeight();
    if (actionBarHeight != 0)
        return actionBarHeight;
    final TypedValue tv = new TypedValue();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))
            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
    } else if (getTheme().resolveAttribute(com.actionbarsherlock.R.attr.actionBarSize, tv, true))
        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
    return actionBarHeight;
}
desarrollador de Android
fuente
9
en caso de que esté usando appcompat, agregue lo siguiente:else if (true == getTheme().resolveAttribute( android.support.v7.appcompat.R.attr.actionBarSize, tv, true)) { actionBarHeight = TypedValue.complexToDimensionPixelSize( tv.data,getResources().getDisplayMetrics()); }
Muzikant
3
"if (true =="? Creo que puedes eliminar el "true" ... :)
desarrollador de Android
Sí, tienes razón ... eso se acaba de agregar para mayor claridad
Muzikant
Según su código, parece que no importa si estoy usando ABS, en todas las versiones anteriores a HONEYCOMB tomará la altura de la barra de acción de android.R.attr.actionBarSize. Es esto correcto ?
AsafK
¿De todos modos es necesario especificar la barra de media acción para ocultar la parte superior de la pantalla? stackoverflow.com/questions/27163374/…
Steve
6

Para establecer la altura de ActionBarusted puede crear nuevos Themecomo este:

<?xml version="1.0" encoding="utf-8"?>
<resources>   
    <style name="Theme.FixedSize" parent="Theme.Sherlock.Light.DarkActionBar">
        <item name="actionBarSize">48dip</item>
        <item name="android:actionBarSize">48dip</item> 
    </style> 
 </resources>

y configura esto Themea tu Activity:

android:theme="@style/Theme.FixedSize"
pajarito
fuente
1
Tenga en cuenta que la altura de la barra de acción es menor en el modo horizontal.
Mark Buikema
No recomiendo esto ya que actionBarSherlock tiene mucho en cuenta al decidir la altura de la barra de acción. Si hace esto, la altura de la barra de acción no se basará en las especificaciones del dispositivo y, por lo tanto, no se verá como la altura estándar para ciertos dispositivos.
Chris Sprague
5

Java:

    int actionBarHeight;
    int[] abSzAttr;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        abSzAttr = new int[] { android.R.attr.actionBarSize };
    } else {
        abSzAttr = new int[] { R.attr.actionBarSize };
    }
    TypedArray a = obtainStyledAttributes(abSzAttr);
    actionBarHeight = a.getDimensionPixelSize(0, -1);

xml:

    ?attr/actionBarSize
TeeTracker
fuente
5

Si está utilizando una barra de herramientas como la barra de acciones,

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

entonces simplemente use el layout_height de la barra de herramientas.

int actionBarHeight = toolbar.getLayoutParams().height;
jk7
fuente
3

puedes usar esta función para obtener la altura de la barra de acción.

public int getActionBarHeight() {
    final TypedArray ta = getContext().getTheme().obtainStyledAttributes(
            new int[] {android.R.attr.actionBarSize});
    int actionBarHeight = (int) ta.getDimension(0, 0);
    return actionBarHeight;
}
wangzhengyi
fuente
2

Este método de ayuda debería ser útil para alguien. Ejemplo:int actionBarSize = getThemeAttributeDimensionSize(this, android.R.attr.actionBarSize);

public static int getThemeAttributeDimensionSize(Context context, int attr)
{
    TypedArray a = null;
    try{
        a = context.getTheme().obtainStyledAttributes(new int[] { attr });
        return a.getDimensionPixelSize(0, 0);
    }finally{
        if(a != null){
            a.recycle();
        }
    }
}
Simón
fuente
2

solo tienes que agregar esto.

public int getActionBarHeight() {
        int height;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            height = getActivity().getActionBar().getHeight();
        } else {
            height = ((ActionBarActivity) getActivity()).getSupportActionBar().getHeight();

        }
        return height;
    }
JCDecary
fuente
2

Encontré una forma más genérica de descubrirlo:

  int[] location = new int[2];
  mainView.getLocationOnScreen(location);
  int toolbarHeight = location[1];

donde ' mainView ' es la vista raíz de su diseño.

La idea es básicamente obtener la posición Y de mainView, ya que se establece justo debajo de la barra de acciones (o barra de herramientas).

Alécio Carvalho
fuente
2

La altura de la barra de acción difiere según el tema aplicado. Si estás usando AppCompatActivity la altura será diferente en la mayoría de los casos de la Actividad normal.

Si está utilizando AppCompatActivity , debe usar R.attr.actionBarSize en lugar de android.R.attr.actionBarSize

public static int getActionBarHeight(Activity activity) {
        TypedValue typedValue = new TypedValue();

        int attributeResourceId = android.R.attr.actionBarSize;
        if (activity instanceof AppCompatActivity) {
            attributeResourceId = R.attr.actionBarSize;
        }

        if (activity.getTheme().resolveAttribute(attributeResourceId, typedValue, true)) {
            return TypedValue.complexToDimensionPixelSize(typedValue.data, activity.getResources().getDisplayMetrics());
        }

        return (int) Math.floor(activity.getResources()
                .getDimension(R.dimen.my_default_value));
    }
Mahmoud
fuente
2

En xml, puede usar? Attr / actionBarSize, pero si necesita acceder a ese valor en Java, debe usar el siguiente código:

public int getActionBarHeight() {
        int actionBarHeight = 0;
        TypedValue tv = new TypedValue();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv,
                    true))
                actionBarHeight = TypedValue.complexToDimensionPixelSize(
                        tv.data, getResources().getDisplayMetrics());
        } else {
            actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,
                    getResources().getDisplayMetrics());
        }
        return actionBarHeight;
    }
Faxriddin Abdullayev
fuente
2

Un método listo para cumplir con la respuesta más popular:

public static int getActionBarHeight(
  Activity activity) {

  int actionBarHeight = 0;
  TypedValue typedValue = new TypedValue();

  try {

    if (activity
      .getTheme()
      .resolveAttribute(
        android.R.attr.actionBarSize,
        typedValue,
        true)) {

      actionBarHeight =
        TypedValue.complexToDimensionPixelSize(
          typedValue.data,
          activity
            .getResources()
            .getDisplayMetrics());
    }

  } catch (Exception ignore) {
  }

  return actionBarHeight;
}
Zon
fuente
2

Aquí hay una versión actualizada con Kotlin que utilicé suponiendo que el teléfono sea más alto que Honeycomb:

val actionBarHeight = with(TypedValue().also {context.theme.resolveAttribute(android.R.attr.actionBarSize, it, true)}) {
            TypedValue.complexToDimensionPixelSize(this.data, resources.displayMetrics)
        }
bboyairwreck
fuente
1

Si está utilizando Xamarin / C #, este es el código que está buscando:

var styledAttributes = Context.Theme.ObtainStyledAttributes(new[] { Android.Resource.Attribute.ActionBarSize });
var actionBarSize = (int)styledAttributes.GetDimension(0, 0);
styledAttributes.Recycle();
Fred
fuente
1
The action bar now enhanced to app bar.So you have to add conditional check for getting height of action bar.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
   height = getActivity().getActionBar().getHeight();
 } else {
  height = ((ActionBarActivity) getActivity()).getSupportActionBar().getHeight();
}
Devraj Singh
fuente
0

Una forma sencilla de encontrar la altura de la barra de acción es desde el onPrepareOptionMenumétodo Actividad .

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
           ....
           int actionBarHeight = getActionBar().getHeight());
           .....
    }
Ashish Jha
fuente
0

En javafx (usando Gluon), la altura se establece en tiempo de ejecución o algo similar. Si bien puede obtener el ancho como de costumbre ...

double width = appBar.getWidth();

Tienes que crear un oyente:

GluonApplication application = this;

application.getAppBar().heightProperty().addListener(new ChangeListener(){
    @Override
    public void changed(ObservableValue observable, Object oldValue, Object newValue) {
        // Take most recent value given here
        application.getAppBar.heightProperty.get()
    }
});

... Y tome el valor más reciente al que cambió. Para obtener la altura.

Lealo
fuente
0

Después de probar todo lo que está ahí fuera sin éxito, descubrí, por accidente, una forma funcional y muy fácil de obtener la altura predeterminada de la barra de acción.

Solo probado en API 25 y 24

C#

Resources.GetDimensionPixelSize(Resource.Dimension.abc_action_bar_default_height_material); 

Java

getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_height_material);
Rafael Pereira
fuente