Como obter a altura do ActionBar?

190

Estou tentando obter a altura do ActionBar(usando Sherlock) toda vez que uma atividade é criada (especialmente para manipular alterações de configuração na rotação, onde a altura do ActionBar pode mudar).

Para isso, eu uso o método ActionBar.getHeight()que funciona apenas quando o ActionBaré mostrado.

Quando a primeira atividade é criada pela primeira vez, posso chamar getHeight()o onCreateOptionsMenuretorno de chamada. Mas esse método não é chamado depois.

Portanto, minha pergunta é quando posso chamar getHeight () e ter certeza de que ele não retorna 0? Ou, se não for possível, como posso definir a altura do ActionBar?

znat
fonte

Respostas:

417

Embora a resposta do @ birdy seja uma opção, se você deseja controlar explicitamente o tamanho da ActionBar, existe uma maneira de puxá-la para cima sem bloquear o tamanho que encontrei na documentação de suporte. É um pouco estranho, mas funcionou para mim. Você precisará de um contexto, este exemplo seria válido em uma Atividade.

// 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)
}
Anthony
fonte
13
ótima ajuda !! mas de onde você encontra todas essas coisas !!
Vikky
5
Geralmente, a partir de pesquisas exaustivas ou buscas no manual do desenvolvedor. Eu acho que o último neste caso, mas já faz um tempo.
31513 Anthony
1
Podemos alterar o tamanho da barra de ação apenas para uma atividade específica?
Sudarshan Bhat
Isso funcionou para mim nos dois casos: (i) onCreateView e (ii) onConfigurationChanged. Obrigado!
Marcelo Noguti 28/11
5
"android.R.attr.actionBarSize" não está funcionando na versão 2.3 do Android, mas "R.attr.actionBarSize" está funcionando com Android em toda a versão. é só usar "R.attr.actionBarSize" em vez de "android.R.attr.actionBarSize", "android.support.v7.appcompat.R.attr.actionBarSize" e etc.
Nathaniel Jobs
147

Em XML, você deve usar este atributo:

android:paddingTop="?android:attr/actionBarSize"
cesards
fonte
20
no caso de você estar usando o ActionBarCompat "@ dimen / abc_action_bar_default_height"
Ali AlNoaimi
10
Obrigado Ali AlNoaimi! Com AppCompat v21, o nome mudou para: "@ dimen / abc_action_bar_default_height_material"
Tony Ceralva
5
Como @muzikant mencionado abaixo, para appcompat, se você quiser usá-lo no código, o atributo correto é android.support.v7.appcompat.R.attr.actionBarSize. Se você quiser usá-lo no layout xml android:paddingTop="?attr/actionBarSize",. Funciona bem em qualquer lugar.
precisa saber é o seguinte
1
Essa solução é maravilhosa quando você está usando um layout de quadro XML personalizado.
Tryp
2
Se eu quiser usar esse atributo, mas negativo, use-o com um preenchimento negativo. Como eu posso fazer isso?
Tiger developer
17

Ok, eu estava pesquisando e acessando este post várias vezes, então acho que será bom ser descrito não apenas para Sherlock, mas também para o appcompat:

Altura da barra de ação usando appCompat

Bem parecido com a descrição do @Anthony, você pode encontrá-lo com o seguinte código (acabei de alterar a ID do recurso):

TypedValue tv = new TypedValue();

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

Problema Pré Sandwitch

Eu precisava da altura da barra de ação porque, nos dispositivos anteriores ao ICE_CREAM_SANDWITCH, minha visualização era sobreposta à barra de ação. Eu tentei configurar android: layout_marginTop = "? Android: attr / actionBarSize", android: layout_marginTop = "? Attr / actionBarSize", definindo sobreposição para exibir / barra de ação e até altura fixa da barra de ação com tema personalizado, mas nada funcionou. É assim que parecia:

problema de sobreposição

Infelizmente, descobri que, com o método descrito acima, recebo apenas metade da altura (suponho que a barra de opções não esteja ocupada), para corrigir completamente o problema, preciso dobrar a altura da barra de ação e tudo parece correto:

sobreposição fixa

Se alguém souber uma solução melhor (do que duplicar o actionBarHeight), ficarei feliz em me avisar quando for do desenvolvimento do iOS e achei a maioria das coisas do modo de exibição do Android bastante confusas :)

Saudações,

hris.to

hris.to
fonte
Eu experimentei a mesma coisa ao usar guias. O problema é que às vezes é difícil detectar guias versus nenhuma guia, pois alguns dispositivos colapsam visualmente as guias na ActionBar base em algumas situações. Então, o que funcionou para mim é justo ActionBar.getHeight(). Dependendo da situação, isso pode funcionar para você também.
TalkLittle
Eu estava enfrentando o problema porque estava apenas considerando a altura da barra de ação e adicionei a altura da 'barra de notificação'. Isso funcionou bem para mim.
Darpan
Você usa FrameLayout e possui layout_gravity="center_vertical"? Mude para "bottom". O Android 2.3 lida com a margem no FrameLaoyut de maneira diferente dos andróides mais recentes.
Oliv
16

A resposta do @Anthony funciona para dispositivos que suportam ActionBare para aqueles que suportam apenas o Sherlock Action Barseguinte método, devem ser usados

    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
fonte
Você pode agrupar o primeiro if com "if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.HONEYCOMB) {}" para evitar erros de tempo de execução nas versões mais antigas do Android.
Marina.Eariel
Para mim, com.actionbarsherlock.R.attr.actionBarSizetrabalhei no Android 2.3 e 4.0, então parece que você pode usá-lo independentemente da versão do Android.
Felix
13

Eu acho que a maneira mais segura seria:

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;
}
desenvolvedor android
fonte
9
caso esteja usando appcompat, adicione o seguinte: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 =="? Acho que você pode remover o "true" ... :)
desenvolvedor Android
Sim, você está certo ... que é apenas adicionado para maior clareza
Muzikant
Pelo seu código, parece que não importa se estou usando o ABS, em todas as versões acima do HONEYCOMB, ele terá a altura da barra de ação de android.R.attr.actionBarSize. Isso está correto?
AsafK
é assim mesmo especificar a barra de meia ação para ocultar a parte superior da tela? stackoverflow.com/questions/27163374/…
Steve
6

Para definir a altura, ActionBarvocê pode criar novos 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>

e defina isso Themepara o seu Activity:

android:theme="@style/Theme.FixedSize"
birdy
fonte
1
Observe que a altura da barra de ação é menor no modo paisagem.
Mark Buikema
Eu não recomendo isso, pois o actionBarSherlock leva muito em consideração ao decidir a altura da barra de ação. Se você fizer isso, a altura da actionBar não será baseada nas especificações do dispositivo e, portanto, não será parecida com a altura padrão de determinados 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
fonte
5

Se você estiver usando uma barra de ferramentas como a ActionBar,

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

basta usar o layout_height da barra de ferramentas.

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

você pode usar esta função para obter a altura da barra de ação.

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
fonte
2

Esse método auxiliar deve ser útil para alguém. Exemplo: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();
        }
    }
}
Simon
fonte
2

você só precisa adicionar isso.

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
fonte
2

Eu encontrei uma maneira mais genérica de descobri-lo:

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

onde ' mainView ' é a visualização raiz do seu layout.

A idéia é basicamente obter a posição Y do mainView, conforme definido logo abaixo da ActionBar (ou Barra de Ferramentas).

Alécio Carvalho
fonte
2

A altura da barra de ação varia de acordo com o tema aplicado. Se você estiver usando AppCompatActivity, a altura será diferente na maioria dos casos da atividade normal.

Se você estiver usando AppCompatActivity , use R.attr.actionBarSize em vez 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
fonte
2

No xml, você pode usar? Attr / actionBarSize, mas se precisar acessar esse valor em Java, precisará usar o código abaixo:

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
fonte
2

Um método pronto para atender a resposta mais 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
fonte
2

Aqui está uma versão atualizada com o Kotlin que usei assumindo que o telefone é superior ao Honeycomb:

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

Se você estiver usando o Xamarin / C #, este é o código que você está procurando:

var styledAttributes = Context.Theme.ObtainStyledAttributes(new[] { Android.Resource.Attribute.ActionBarSize });
var actionBarSize = (int)styledAttributes.GetDimension(0, 0);
styledAttributes.Recycle();
Fred
fonte
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
fonte
0

Uma maneira simples de encontrar a altura da barra de ação é usando o onPrepareOptionMenumétodo Activity .

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

No javafx (usando Gluon), a altura é definida em tempo de execução ou algo parecido. Embora seja capaz de obter a largura como normalmente ...

double width = appBar.getWidth();

Você precisa criar um ouvinte:

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

... E use o valor mais recente para o qual foi alterado. Para obter a altura.

Lealo
fonte
0

Depois de tentar tudo o que está por aí sem sucesso, descobri, por acidente, uma maneira funcional e muito fácil de obter a altura padrão da barra de ação.

Testado apenas nas API 25 e 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
fonte