Come ottenere l'altezza di ActionBar?


190

Sto cercando di ottenere l'altezza di ActionBar(usando Sherlock) ogni volta che viene creata un'attività (specialmente per gestire le modifiche alla configurazione in rotazione dove l'altezza di ActionBar potrebbe cambiare).

Per questo uso il metodo ActionBar.getHeight()che funziona solo quando ActionBarviene mostrato.

Quando la prima attività viene creata per la prima volta, posso richiamare getHeight()il onCreateOptionsMenucallback. Ma questo metodo non è chiamato dopo.

Quindi la mia domanda è quando posso chiamare getHeight () e avere la certezza che non restituisce 0? O se non è possibile, come posso impostare l'altezza di ActionBar?

Risposte:


419

Mentre la risposta di @ birdy è un'opzione se vuoi controllare esplicitamente la dimensione di ActionBar, c'è un modo per tirarla su senza bloccare la dimensione che ho trovato nella documentazione di supporto. È un po 'imbarazzante ma ha funzionato per me. Avrai bisogno di un contesto, questo esempio sarebbe valido in un'attività.

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

13
grande aiuto !! ma da dove trovi tutte queste cose !!
Vikky

5
Generalmente da google esaustivo o trascinamento attraverso il manuale dello sviluppatore. Penso che quest'ultimo in questo caso, ma è passato un po 'di tempo.
Anthony,

1
Possiamo modificare le dimensioni della barra delle azioni solo per una determinata attività?
Sudarshan Bhat,

Ciò ha funzionato per me in entrambi i casi: (i) onCreateView e (ii) onConfigurationChanged. Grazie!
Marcelo Noguti,

5
"android.R.attr.actionBarSize" non funziona in Android versione 2.3, ma "R.attr.actionBarSize" funziona Android in tutte le versioni. basta usare "R.attr.actionBarSize" invece di "android.R.attr.actionBarSize", "android.support.v7.appcompat.R.attr.actionBarSize" e così via
Nathaniel Jobs

148

In XML, dovresti usare questo attributo:

android:paddingTop="?android:attr/actionBarSize"

20
nel caso in cui si utilizzi ActionBarCompat "@ dimen / abc_action_bar_default_height"
Ali AlNoaimi

10
Grazie Ali AlNoaimi! Con AppCompat v21 il nome è stato cambiato in: "@ dimen / abc_action_bar_default_height_material"
Tony Ceralva,

5
Come @muzikant menzionato di seguito, per appcompat, se si desidera utilizzarlo nel codice, l'attributo corretto è android.support.v7.appcompat.R.attr.actionBarSize. Se si desidera utilizzarlo nel layout xml, android:paddingTop="?attr/actionBarSize". Funziona bene ovunque.
rpattabi,

1
Questa soluzione è meravigliosa quando si utilizza un framelayout XML personalizzato.
tryp

2
Se voglio usare questo attr ma negativo per usarlo con un'imbottitura negativa. Come lo posso fare?
Sviluppatore Tiger il

17

Ok, ho cercato su Google e ho ricevuto questo post diverse volte, quindi penso che sarà bello essere descritto non solo per Sherlock ma anche per appcompat:

Altezza della barra delle azioni utilizzando appCompat

Abbastanza simile alla descrizione di @Anthony, potresti trovarlo con il seguente codice (ho appena cambiato l'ID della risorsa):

TypedValue tv = new TypedValue();

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

Problema pre-sandwitch

Avevo bisogno dell'altezza della barra delle azioni perché sui dispositivi ICE_CREAM_SANDWITCH precedenti la mia vista era sovrapposta alla barra delle azioni. Ho provato a impostare android: layout_marginTop = "? Android: attr / actionBarSize", android: layout_marginTop = "? Attr / actionBarSize", impostando la sovrapposizione su view / actionbar e persino fissando l'altezza della barra di azione con un tema personalizzato ma nulla ha funzionato. Ecco come appariva:

problema di sovrapposizione

Sfortunatamente ho scoperto che con il metodo descritto sopra ottengo solo metà dell'altezza (suppongo che la barra delle opzioni non sia stata posizionata) quindi per risolvere completamente il problema ho bisogno di raddoppiare l' altezza della barra delle azioni e tutto sembra ok:

sovrapposizione fissa

Se qualcuno conosce una soluzione migliore (che raddoppiare actionBarHeight), sarò felice di farmi sapere come vengo dallo sviluppo di iOS e ho trovato la maggior parte delle cose di Android view piuttosto confuse :)

Saluti,

hris.to


Ho provato la stessa cosa quando ho usato le schede. Il problema è che a volte è difficile rilevare le schede anziché le schede, poiché alcuni dispositivi comprimono visivamente le schede nella ActionBar di base in alcune situazioni. Quindi quello che ha funzionato per me è giusto ActionBar.getHeight(). A seconda della situazione, potrebbe funzionare anche per te.
TalkLittle

Stavo affrontando il problema perché stavo solo considerando l'altezza della barra delle azioni, quindi ho aggiunto anche l'altezza della "barra delle notifiche". Ha funzionato bene nel mio caso.
Darpan,

Usi FrameLayout e hai layout_gravity="center_vertical"? Modificalo in "bottom". Android 2.3 gestisce il margine in FrameLaoyut in modo diverso rispetto ai nuovi androidi.
Oliv

16

@Anthony answer funziona per i dispositivi che supportano ActionBare per quei dispositivi che supportano solo il Sherlock Action Barseguente metodo

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

Puoi racchiudere il primo if con "if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.HONEYCOMB) {}" per evitare errori di runtime su versioni precedenti di Android.
Marina.Eariel,

Per me ha com.actionbarsherlock.R.attr.actionBarSizefunzionato sia con Android 2.3 che 4.0, quindi sembra che tu possa usarlo indipendentemente dalla versione di Android.
Felix,

13

penso che il modo più sicuro sarebbe:

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

9
nel caso in cui si stia utilizzando appcompat, aggiungere quanto segue: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 =="? Penso che tu possa rimuovere il "vero" ... :)
sviluppatore Android il

Sì, hai ragione ... questo è appena stato aggiunto per chiarezza
Muzikant,

Dal tuo codice sembra che non abbia importanza se sto usando ABS, in tutte le versioni sopra HONEYCOMB prenderà l'altezza della barra delle azioni da android.R.attr.actionBarSize. È corretto ?
AsafK

è comunque specificare la mezza barra di azione per nascondere la parte superiore dello schermo? stackoverflow.com/questions/27163374/…
Steve

6

Per impostare l'altezza di ActionBarte puoi crearne di nuovi Themecome questo:

<?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 impostalo Themesul tuo Activity:

android:theme="@style/Theme.FixedSize"

1
Si noti che l'altezza della barra delle azioni è inferiore in modalità orizzontale.
Mark Buikema,

Non lo consiglio poiché actionBarSherlock tiene molto conto quando decide l'altezza della barra delle azioni. Se lo fai, l'altezza della barra delle azioni non sarà basata sulle specifiche del dispositivo e quindi non sembrerà l'altezza standard per alcuni dispositivi.
Chris Sprague,

5

Giava:

    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

5

Se si utilizza una barra degli strumenti come ActionBar,

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

quindi basta usare layout_height della barra degli strumenti.

int actionBarHeight = toolbar.getLayoutParams().height;

3

puoi usare questa funzione per ottenere l'altezza della barra delle azioni.

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

2

Questo metodo di aiuto dovrebbe tornare utile per qualcuno. Esempio: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();
        }
    }
}

2

devi solo aggiungere questo.

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

2

Ho trovato un modo più generico per scoprirlo:

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

dove ' mainView ' è la vista principale del layout.

L'idea è fondamentalmente di ottenere la posizione Y del mainView in quanto è impostato proprio sotto la ActionBar (o la barra degli strumenti).


2

L'altezza della barra delle azioni varia in base al tema applicato. Se stai usando AppCompatActivity l'altezza sarà nella maggior parte dei casi diversa dalla normale Attività.

Se stai usando AppCompatActivity dovresti usare R.attr.actionBarSize invece di 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));
    }

2

In XML, puoi usare? Attr / actionBarSize, ma se hai bisogno di accedere a quel valore in Java devi usare il codice seguente:

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

2

Un metodo pronto per soddisfare la risposta più popolare:

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

2

Ecco una versione aggiornata con Kotlin che ho usato supponendo che il telefono sia superiore a Honeycomb:

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

1

Se stai usando Xamarin / C #, questo è il codice che stai cercando:

var styledAttributes = Context.Theme.ObtainStyledAttributes(new[] { Android.Resource.Attribute.ActionBarSize });
var actionBarSize = (int)styledAttributes.GetDimension(0, 0);
styledAttributes.Recycle();

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

0

Un modo semplice per trovare l'altezza della barra delle azioni è dal onPrepareOptionMenumetodo Activity .

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

0

In javafx (usando Gluon), l'altezza è impostata in fase di esecuzione o qualcosa del genere. Pur essendo in grado di ottenere la larghezza come normale ...

double width = appBar.getWidth();

Devi creare un ascoltatore:

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 prendi il valore più recente in cui è cambiato. Per ottenere l'altezza.


0

Dopo aver provato tutto ciò che è là fuori senza successo, ho scoperto, per caso, un modo funzionale e molto semplice per ottenere l'altezza predefinita della barra delle azioni.

Testato solo in API 25 e 24

C #

Resources.GetDimensionPixelSize(Resource.Dimension.abc_action_bar_default_height_material); 

Giava

getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_height_material);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.