Как получить высоту ActionBar?

Я пытаюсь получить высоту ActionBar (используя Sherlock) каждый раз, когда создается действие (специально для обработки изменений конфигурации при вращении, где высота ActionBar может измениться).

для этого я использую метод ActionBar.getHeight() работает только когда Это.

когда первое действие создается в первый раз, я могу вызвать getHeight() на onCreateOptionsMenu обратный. Но этот метод не вызывается после.

Итак, мой вопрос, когда могу ли я вызвать getHeight () и быть уверенным, что он не возвращает 0? Или, если это невозможно, как я могу установить высоту ActionBar ?

20 ответов


хотя ответ @birdy является опцией, если вы хотите явно контролировать размер ActionBar, есть способ вытащить его без блокировки размера, который я нашел в документации поддержки. Это немного неловко, но у меня получилось. Вам понадобится контекст, этот пример будет действителен в действии.

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

в XML, вы должны использовать этот атрибут:

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

хорошо, я гуглил и добирался до этого поста несколько раз, поэтому я думаю, что будет хорошо быть описанным не только для Шерлока, но и для appcompat:

высота панели действий с помощью appCompat

довольно похоже на описание @Anthony вы можете найти его со следующим кодом (я только что изменил идентификатор ресурса):

TypedValue tv = new TypedValue();

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

Предварительная Проблема Sandwitch

Мне нужна высота панели действий, потому что на pre ICE_CREAM_SANDWITCH устройства, которые я видел, перекрывали панель действий. Я попытался установить android: layout_marginTop="?android: attr / actionBarSize", android: layout_marginTop="?attr / actionBarSize", установка перекрытия для просмотра / actionbar и даже фиксированная высота actionbar с пользовательской темой, но ничего не работало. Вот как это выглядело:

overlap problem

к сожалению, я узнал, что с описанным выше методом я получаю только половину высоты(я предполагаю, что панель опций не занята), поэтому полностью исправить isue мне нужно двойной высота панели действий, и все кажется ОК:

overlap fixed

Если кто-то знает лучшее решение(чем удвоение actionBarHeight), я буду рад сообщить мне, как я пришел из разработки iOS, и я нашел большинство вещей Android view довольно запутанными :)

С уважением,

hris.к


@Anthony answer работает для устройств, поддерживающих 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());
   }

Я думаю, что самым безопасным способом было бы:

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

установить высоту 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"

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

вы можете использовать эту функцию для получения высоты actionbar.

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

этот вспомогательный метод должен пригодиться кому-то. Пример: 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();
        }
    }
}

вы просто должны добавить этот.

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

высота панели действий отличается в зависимости от применяемой темы. Если вы используете 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));
    }

Если вы используете панель инструментов как в ActionBar,

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

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

int actionBarHeight = toolbar.getLayoutParams().height;

Если вы используете Xamarin / C#, это код, который вы ищете:

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

Я нашел более общий способ обнаружить его:

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

где 'представлении MainView - это корневой вид вашего макета.

идея в основном получить позицию Y представлении MainView поскольку он установлен прямо под панелью действий (или панелью инструментов).


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

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

простой способ найти высоту actionbar от Activity onPrepareOptionMenu метод.

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

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

...И возьмите самое последнее значение, на которое он изменился. Чтобы получить высоту.


после попытки все, что там без успеха, я узнал, случайно, функциональный и очень простой способ получить высоту панели действий по умолчанию.

тестируется только в 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);

готовый метод для выполнения самого популярного ответа:

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