Wie erhalte ich die ActionBar-Höhe?


190

Ich versuche, die Höhe des ActionBar(mit Sherlock) jedes Mal zu ermitteln, wenn eine Aktivität erstellt wird (insbesondere, um Konfigurationsänderungen bei Drehung zu behandeln, bei denen sich die ActionBar-Höhe ändern kann).

Dafür verwende ich die Methode, ActionBar.getHeight()die nur funktioniert, wenn die ActionBarangezeigt wird.

Wenn die erste Aktivität zum ersten Mal erstellt wird, kann ich getHeight()den onCreateOptionsMenuRückruf anrufen . Diese Methode wird jedoch nicht aufgerufen.

Meine Frage ist also, wann ich getHeight () aufrufen und sicher sein kann, dass es nicht 0 zurückgibt. Oder wenn es nicht möglich ist, wie kann ich die Höhe der ActionBar einstellen?

Antworten:


417

Während die Antwort von @ birdy eine Option ist, wenn Sie die ActionBar-Größe explizit steuern möchten, gibt es eine Möglichkeit, sie aufzurufen, ohne die Größe zu sperren, die ich in der Support-Dokumentation gefunden habe. Es ist etwas umständlich, aber es hat bei mir funktioniert. Sie benötigen einen Kontext. Dieses Beispiel ist in einer Aktivität gültig.

// 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
tolle Hilfe !! aber woher findest du all diese Dinge !!
Vikky

5
Im Allgemeinen von erschöpfendem Googeln oder Plackern durch das Entwicklerhandbuch. Ich denke, letzteres in diesem Fall, aber es ist eine Weile her.
Anthony

1
Können wir die Größe der Aktionsleiste nur für eine bestimmte Aktivität ändern?
Sudarshan Bhat

Dies funktionierte in beiden Fällen für mich: (i) onCreateView und (ii) onConfigurationChanged. Vielen Dank!
Marcelo Noguti

5
"android.R.attr.actionBarSize" funktioniert nicht in Android Version 2.3, aber "R.attr.actionBarSize" funktioniert in Android allen Versionen. Verwenden Sie einfach "R.attr.actionBarSize" anstelle von "android.R.attr.actionBarSize", "android.support.v7.appcompat.R.attr.actionBarSize" usw.
Nathaniel Jobs

147

In XML sollten Sie dieses Attribut verwenden:

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

20
falls Sie ActionBarCompat "@ dimen / abc_action_bar_default_height" verwenden
Ali AlNoaimi

10
Danke Ali AlNoaimi! Mit AppCompat v21 wurde der Name in "@ dimen / abc_action_bar_default_height_material" geändert
Tony Ceralva

5
Wie @muzikant unten erwähnt, ist für appcompat das richtige Attribut, wenn Sie es im Code verwenden möchten android.support.v7.appcompat.R.attr.actionBarSize. Wenn Sie es in Layout-XML verwenden möchten , android:paddingTop="?attr/actionBarSize". Funktioniert überall gut.
Rpattabi

1
Diese Lösung ist wunderbar, wenn Sie ein benutzerdefiniertes XML-Framelayout verwenden.
Tryp

2
Wenn ich dieses attr aber negativ verwenden möchte, um es mit einer negativen Polsterung zu verwenden. Wie kann ich das machen?
Tiger Entwickler

17

Ok, ich habe mehrmals gegoogelt und bin zu diesem Beitrag gekommen, daher denke ich, dass es gut ist, nicht nur für Sherlock, sondern auch für Appcompat beschrieben zu werden:

Höhe der Aktionsleiste mit appCompat

Ähnlich wie bei der @ Anthony-Beschreibung finden Sie sie mit folgendem Code (ich habe gerade die Ressourcen-ID geändert):

TypedValue tv = new TypedValue();

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

Pre Sandwitch Problem

Ich benötigte die Höhe der Aktionsleiste, da meine Ansicht auf Geräten vor ICE_CREAM_SANDWITCH die Aktionsleiste überlappte. Ich habe versucht, android: layout_marginTop = "? Android: attr / actionBarSize", android: layout_marginTop = "? Attr / actionBarSize" einzustellen, Überlappung auf view / actionbar und sogar feste Actionbar-Höhe mit benutzerdefiniertem Thema festzulegen, aber nichts hat funktioniert. So sah es aus:

Überlappungsproblem

Leider habe ich herausgefunden, dass ich mit der oben beschriebenen Methode nur die Hälfte der Höhe erhalte (ich gehe davon aus, dass die Optionsleiste nicht vorhanden ist). Um das Problem vollständig zu beheben, muss ich die Höhe der Aktionsleiste verdoppeln und alles scheint in Ordnung zu sein:

Überlappung behoben

Wenn jemand eine bessere Lösung kennt (als actionBarHeight zu verdoppeln), werde ich mich freuen, es mir mitzuteilen, da ich aus der iOS-Entwicklung stamme und die meisten Dinge in der Android-Ansicht ziemlich verwirrend fanden :)

Grüße,

hris.to.


Ich habe das gleiche erlebt, als ich Tabs verwendet habe. Das Problem ist, dass es manchmal schwierig ist, Registerkarten im Vergleich zu keinen Registerkarten zu erkennen, da einige Geräte die Registerkarten in bestimmten Situationen visuell in der Basis-Aktionsleiste zusammenklappen. Also, was für mich funktioniert hat, ist gerecht ActionBar.getHeight(). Je nach Situation kann dies auch für Sie funktionieren.
TalkLittle

Ich hatte das Problem, weil ich nur die Höhe der Aktionsleiste berücksichtigte und dann auch die Höhe der Benachrichtigungsleiste hinzufügte. Es hat gut für mich funktioniert.
Darpan

Verwenden Sie FrameLayout und haben layout_gravity="center_vertical"? Ändern Sie es in "bottom". Android 2.3 behandelt den Rand in FrameLaoyut anders als neuere Androiden.
Oliv

16

Die @ Anthony-Antwort funktioniert für Geräte, die unterstützen, ActionBarund für Geräte, die nur die Sherlock Action Barfolgende Methode unterstützen, muss verwendet werden

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

Sie können das erste if mit "if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.HONEYCOMB) {}" umschließen, um Laufzeitfehler bei älteren Android-Versionen zu vermeiden.
Marina.Eariel

Für mich hat com.actionbarsherlock.R.attr.actionBarSizesowohl für Android 2.3 als auch für 4.0 gearbeitet, es sieht also so aus, als könnten Sie dies unabhängig von der Android-Version verwenden.
Felix

13

Ich denke, der sicherste Weg wäre:

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
Wenn Sie Appcompat verwenden, fügen Sie Folgendes hinzu: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 =="? Ich denke, Sie können die "true" entfernen ... :)
Android-Entwickler

Ja, Sie haben Recht ... das wurde nur aus Gründen der Klarheit hinzugefügt
Muzikant

Aus Ihrem Code geht hervor, dass es keine Rolle spielt, ob ich ABS verwende. In allen Versionen über HONEYCOMB wird die Höhe der Aktionsleiste von android.R.attr.actionBarSize übernommen. Ist das richtig ?
AsafK

Ist es trotzdem möglich, die halbe Aktionsleiste anzugeben, um den oberen Bildschirmrand auszublenden? stackoverflow.com/questions/27163374/…
Steve

6

Um die Höhe von ActionBarfestzulegen, können Sie neue Themewie diese erstellen :

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

und setzen Sie dies Themeauf Ihre Activity:

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

1
Beachten Sie, dass die Höhe der Aktionsleiste im Querformat kleiner ist.
Mark Buikema

Ich empfehle dies nicht, da actionBarSherlock bei der Festlegung der Höhe der Aktionsleiste viel berücksichtigt. In diesem Fall basiert die actionBar-Höhe nicht auf den Gerätespezifikationen und entspricht daher nicht der Standardhöhe für bestimmte Geräte.
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

5

Wenn Sie eine Symbolleiste als Aktionsleiste verwenden,

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

Verwenden Sie dann einfach die layout_height der Symbolleiste.

int actionBarHeight = toolbar.getLayoutParams().height;

3

Mit dieser Funktion können Sie die Höhe der Aktionsleiste ermitteln.

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

Diese Hilfsmethode sollte für jemanden nützlich sein. Beispiel: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

Sie müssen dies nur hinzufügen.

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

Ich habe einen allgemeineren Weg gefunden, es zu entdecken:

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

Dabei ist ' mainView ' die Stammansicht Ihres Layouts.

Die Idee ist im Grunde, die Y-Position der Hauptansicht zu erhalten, da sie direkt unter der Aktionsleiste (oder Symbolleiste) festgelegt ist.


2

Die Höhe der Aktionsleiste unterscheidet sich je nach angewendetem Thema. Wenn Sie AppCompatActivity verwenden, unterscheidet sich die Höhe in den meisten Fällen von der normalen Aktivität.

Wenn Sie AppCompatActivity verwenden , sollten Sie R.attr.actionBarSize anstelle von android.R.attr.actionBarSize verwenden

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 können Sie? Attr / actionBarSize verwenden. Wenn Sie jedoch Zugriff auf diesen Wert in Java benötigen, müssen Sie den folgenden Code verwenden:

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

Eine fertige Methode, um die beliebteste Antwort zu erfüllen:

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

Hier ist eine aktualisierte Version mit Kotlin, die ich verwendet habe, vorausgesetzt, das Telefon ist höher als Honeycomb:

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

1

Wenn Sie Xamarin / C # verwenden, ist dies der Code, nach dem Sie suchen:

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

Eine einfache Möglichkeit, die Höhe der Aktionsleiste zu ermitteln, ist die Aktivitätsmethode onPrepareOptionMenu.

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

0

In javafx (mit Gluon) wird die Höhe zur Laufzeit oder ähnlichem eingestellt. Während Sie in der Lage sind, die Breite wie gewohnt zu erhalten ...

double width = appBar.getWidth();

Sie müssen einen Listener erstellen:

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

... und nehmen Sie den letzten Wert, zu dem er geändert wurde. Um die Höhe zu bekommen.


0

Nachdem ich alles, was da draußen ist, ohne Erfolg ausprobiert hatte, fand ich zufällig eine funktionale und sehr einfache Möglichkeit, die Standardhöhe der Aktionsleiste zu ermitteln.

Nur in API 25 und 24 getestet

C #

Resources.GetDimensionPixelSize(Resource.Dimension.abc_action_bar_default_height_material); 

Java

getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_height_material);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.