Як отримати висоту ActionBar?


190

Я намагаюся отримати висоту ActionBar(за допомогою Шерлока) кожного разу, коли створюється діяльність (спеціально для обробки змін конфігурації при обертанні, де висота ActionBar може змінюватися).

Для цього я використовую метод, ActionBar.getHeight()який працює лише тоді, коли ActionBarпоказано.

Коли перша активність створена вперше, я можу зателефонувати getHeight()у onCreateOptionsMenuзворотній дзвінок. Але цей метод не називається після.

Отже, моє запитання полягає в тому, коли я можу зателефонувати getHeight () і бути впевненим, що він не поверне 0? Або якщо це неможливо, як я можу встановити висоту ActionBar?

Відповіді:


419

Хоча відповідь @ birdy - це варіант, якщо ви хочете чітко контролювати розмір ActionBar, є спосіб витягнути його, не блокуючи розмір, який я знайшов у документації з підтримки. Це трохи незручно, але це працює для мене. Вам знадобиться контекст, цей приклад буде дійсним у діяльності.

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

Котлін :

val tv = TypedValue()
if (requireActivity().theme.resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
    val actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, resources.displayMetrics)
}

13
чудова допомога !! але звідки ви знайдете всі такі речі !!
vikky

5
Як правило, від вичерпного гуглінгу чи друзів через посібник для розробників. Я думаю, що останнє в цьому випадку, але минув певний час.
Ентоні

1
Чи можемо ми змінити розмір панелі дій лише для певної діяльності?
Sudarshan Bhat

Це працювало для мене в обох випадках: (i) onCreateView та (ii) onConfigurationChanged. Дякую!
Марсело Ногуті

5
"android.R.attr.actionBarSize" не працює у версії 2.3 для Android, але "R.attr.actionBarSize" працює в Android для всіх версій. просто використовуйте "R.attr.actionBarSize" замість "android.R.attr.actionBarSize", "android.support.v7.appcompat.R.attr.actionBarSize" і т. д.
Nathaniel Jobs

148

У XML слід використовувати цей атрибут:

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

20
якщо ви використовуєте ActionBarCompat "@ dimen / abcgery_bar_default_height"
Ali AlNoaimi

10
Дякую Алі АльНоаїмі! З AppCompat v21 ім'я змінилося на: "@ dimen / abcgery_bar_default_height_material"
Tony Ceralva

5
Як зазначено нижче @muzikant, для appcompat, якщо ви хочете використовувати його в коді, правильний атрибут android.support.v7.appcompat.R.attr.actionBarSize. Якщо ви хочете використовувати його в макет XML, android:paddingTop="?attr/actionBarSize". Працює чудово скрізь.
рпаттабі

1
Це рішення є чудовим, коли ви використовуєте нестандартний XML-кадр.
tryp

2
Якщо я хочу використовувати цей attr, але негативний, використовувати його з негативним накладом. Як я можу це зробити?
розробник Tiger

17

Добре, я кілька разів гуляв і дійшов до цієї публікації, тому я думаю, що це буде добре описати не лише для Шерлока, але і для appcompat:

Висота смуги дій за допомогою appCompat

Досить подібний до @Anthony опису, ви можете знайти його з наступним кодом (я щойно змінив ідентифікатор ресурсу):

TypedValue tv = new TypedValue();

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

Попередня проблема з сендвіч

Мені потрібна була висота смуги дій, оскільки на пристроях, що передували ICE_CREAM_SANDWITCH, мій погляд перекривався смугою дій. Я спробував встановити android: layout_marginTop = "? Android: attr / actionBarSize", android: layout_marginTop = "? Attr / actionBarSize", встановивши перекриття для перегляду / панелі дій і навіть фіксовану висоту панелі дій з власною темою, але нічого не працювало. Ось як це виглядало:

проблема перекриття

На жаль, я виявив, що за описаним вище методом я отримую лише половину висоти (я припускаю, що панель параметрів не взята на місце), тому для повного виправлення іску мені потрібно подвоїти висоту смуги дій, і все здається нормально:

перекриття фіксовано

Якщо хтось знає краще рішення (ніж подвоєння actionBarHeight), я буду радий повідомити мене, як я вийшов з розробки iOS, і я виявив, що більшість матеріалів перегляду Android є досить заплутаними :)

З повагою,

hris.to


Я зазнав те саме, коли користувався вкладками. Проблема полягає в тому, що іноді важко виявити вкладки порівняно з відсутніми вкладками, оскільки деякі пристрої в деяких ситуаціях візуально згортають вкладки в базовий ActionBar. Тож те, що працювало для мене, справедливе ActionBar.getHeight(). Залежно від ситуації, це може працювати і для вас.
TalkLittle

Я зіткнувся з проблемою, тому що я розглядав лише висоту панелі дій, а потім додав і висоту "панелі сповіщень". Це добре спрацювало для мене.
Дарпан

Ви використовуєте FrameLayout і маєте layout_gravity="center_vertical"? Змініть його на "bottom". Android 2.3 обробляє маржу в FrameLaoyut інакше, ніж новіші андроїди.
Олів

16

@Anthony відповідь працює для пристроїв, які підтримують, ActionBarі для тих пристроїв, які підтримують лише Sherlock Action Barнаступний метод

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

Першим можна обернути слово "if" (Build.VERSION.SDK_INT> = Build.VERSION_CODES.HONEYCOMB) {} ", щоб уникнути помилок під час виконання старіших версій Android.
Marina.Eariel

Для мене com.actionbarsherlock.R.attr.actionBarSizeпрацювали як для Android 2.3, так і для 4.0, тому, схоже, ви можете використовувати це незалежно від версії Android.
Фелікс

13

я думаю, що найбезпечнішим способом було б:

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
якщо ви користуєтеся програмою appcompat, додайте наступне: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 =="? Я думаю, ви можете видалити "true" ... :)
андроїд розробник

Так, ти маєш рацію ... це лише додано для ясності
Muzikant

З вашого коду виглядає, що це не має значення, якщо я використовую ABS, у всіх версіях вище HONEYCOMB це займе висоту панелі дій від android.R.attr.actionBarSize. Це правильно ?
AsafK

чи все-таки потрібно вказати половину дії, щоб приховати верхню частину екрана? stackoverflow.com/questions/27163374/…
Стів

6

Щоб встановити висоту, ActionBarви можете створити Themeтакий, як цей:

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

і встановіть це Themeдля свого Activity:

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

1
Зауважте, що висота смуги дій у ландшафтному режимі менша.
Марк Буйкема

Я не рекомендую цього, оскільки actionBarSherlock багато враховує при визначенні висоти панелі дій. Якщо ви це зробите, висота діїBar не буде базуватися на специфікаціях пристрою, а отже, не буде схожа на стандартну висоту для певних пристроїв.
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

Якщо ви використовуєте Панель інструментів як панель дій,

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

потім просто використовуйте layout_height панелі інструментів.

int actionBarHeight = toolbar.getLayoutParams().height;

3

Ви можете використовувати цю функцію для отримання висоти панелі дій.

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

Цей помічний метод повинен комусь стати в нагоді. Приклад: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

ви просто повинні додати це.

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

Я знайшов більш загальний спосіб її виявити:

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

де " mainView " - це кореневий вигляд вашого макета.

В основному ідея полягає в Y-положенні mainView, оскільки воно встановлено прямо під панеллю ActionBar (або Панель інструментів).


2

Висота панелі дій відрізняється залежно від застосованої теми. Якщо ви використовуєте AppCompatActivity висота в більшості випадків буде відрізнятися від звичайної активності.

Якщо ви використовуєте AppCompatActivity, ви повинні використовувати R.attr.actionBarSize замість 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

У xml ви можете використовувати? Attr / actionBarSize, але якщо вам потрібен доступ до цього значення на Java, вам потрібно використовувати код нижче:

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

Готовий спосіб виконати найпопулярнішу відповідь:

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

Ось оновлена ​​версія з Котліном, я використовував припущення, що телефон вище, ніж стільник:

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

1

Якщо ви використовуєте Xamarin / C #, це код, який ви шукаєте:

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

Простий спосіб знайти висоту панелі дій - це onPrepareOptionMenuметод Activity .

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

0

У javafx (за допомогою Gluon) висота встановлюється під час виконання або щось подібне. Маючи можливість отримати ширину, як звичайну ...

double width = appBar.getWidth();

Ви повинні створити слухача:

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

... І візьміть останнє значення, на яке воно змінилося. Щоб отримати висоту.


0

Спробувавши все, що там є без успіху, я випадково виявив функціональний і дуже простий спосіб отримати висоту панелі дій за замовчуванням.

Тестується лише в API 25 і 24

C #

Resources.GetDimensionPixelSize(Resource.Dimension.abc_action_bar_default_height_material); 

Java

getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_height_material);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.