如何获得ActionBar的高度?


190

我试图在ActionBar每次创建活动时获取(使用Sherlock)的高度(特别是处理ActionBar高度可能发生变化的旋转配置变化)。

为此,我使用ActionBar.getHeight()仅在ActionBar显示时有效的方法。

当第一次创建的第一个活动,我可以调用getHeight()onCreateOptionsMenu回调。但是此方法未在之后调用。

所以我的问题是何时可以调用getHeight()并确保它不会返回0?或者,如果不可能,如何设置ActionBar的高度?

Answers:


417

如果您想显式控制ActionBar的大小,则@birdy的答案是一个选择,但是有一种方法可以拉起它而不锁定我在支持文档中找到的大小。有点尴尬,但对我有用。您需要一个上下文,此示例在Activity中有效。

// 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
通常是通过详尽的Google搜索或通过开发人员手册来获取。在这种情况下,我认为是后者,但是已经有一段时间了。
安东尼

1
我们可以仅针对特定活动更改操作栏大小吗?
Sudarshan Bhat 2013年

这在两种情况下都对我有用:(i)onCreateView和(ii)onConfigurationChanged。谢谢!
Marcelo Noguti 2014年

5
“ android.R.attr.actionBarSize”在android 2.3版中不起作用,但是“ R.attr.actionBarSize”在android所有版本中均起作用。只需使用“ R.attr.actionBarSize”代替“ android.R.attr.actionBarSize”,“ android.support.v7.appcompat.R.attr.actionBarSize”等。–
纳撒尼尔·乔布斯

147

在XML中,应使用以下属性:

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

20
如果您使用的是ActionBarCompat“ @ dimen / abc_action_bar_default_height”
Ali AlNoaimi 2014年

10
感谢Ali AlNoaimi!使用AppCompat v21时,名称已更改为:“ @ dimen / abc_action_bar_default_height_material”
Tony Ceralva 2015年

5
如下面@muzikant所述,对于appcompat,如果要在代码中使用它,则正确的属性为android.support.v7.appcompat.R.attr.actionBarSize。如果要在布局xml中使用它,请参见android:paddingTop="?attr/actionBarSize"。在任何地方都可以正常工作。
rpattabi 2015年

1
当您使用自定义XML框架布局时,此解决方案非常好。
tryp,2016年

2
如果我想使用此attr但为负数,请使用它带有负填充。我怎样才能做到这一点?
Tiger开发者

17

好吧,我在谷歌上搜索了几次,所以我认为不仅对Sherlock进行描述,对于appcompatpat也将是很好的描述:

使用appCompat的操作栏高度

与@Anthony描述非常相似,您可以使用以下代码找到它(我刚刚更改了资源ID):

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 2014年

我遇到的问题是,我只考虑操作栏的高度,然后我还添加了“通知栏”的高度。对我来说效果很好。
2015年

您是否使用FrameLayout并拥有layout_gravity="center_vertical"?将其更改为"bottom"。Android 2.3在FrameLaoyut中处理利润的方式与更新的android不同。
奥利夫,2015年

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){}”包装第一个if,以避免在旧版Android上出现运行时错误。
Marina.Eariel

对我来说,我com.actionbarsherlock.R.attr.actionBarSize在Android 2.3和4.0上都工作过,因此无论Android版本如何,您都可以使用它。
Felix

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 2014年

3
“ if(true ==”?我认为您可以删除“ true” ... :)
android开发人员

是的,您是对的...只是为了清楚起见而添加
Muzikant

从您的代码看来,即时通讯是否使用ABS并不重要,在HONEYCOMB以上的所有版本中,它将采用android.R.attr.actionBarSize中的操作栏高度。这样对吗 ?
AsafK 2014年

是否指定半操作栏以隐藏屏幕顶部?stackoverflow.com/questions/27163374/…–
史蒂夫(Steve)

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
请注意,在横向模式下,操作栏的高度较小。
Mark Buikema

我不建议这样做,因为在确定操作栏高度时,考虑了actionBarSherlock。如果执行此操作,则actionBar的高度将不会基于设备规格,因此不会像某些设备的标准高度那样。
克里斯·斯普拉格

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

如果您将工具栏用作ActionBar,

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 ”是布局的根视图。

这个想法基本上是获得mainView的Y位置,因为它位于ActionBar(或Toolbar)的正下方。


2

动作栏的高度根据所应用的主题而不同。如果您使用的是AppCompatActivity,则高度在大多数情况下会与正常的Activity不同。

如果您使用的是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

这是Kotlin的更新版本,我假设手机比Honeycomb高:

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

查找动作栏高度的一种简单方法是使用Activity onPrepareOptionMenu方法。

@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); 

爪哇

getResources().getDimensionPixelSize(R.dimen.abc_action_bar_default_height_material);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.