如何获得 ActionBar 的高度?

Posted

技术标签:

【中文标题】如何获得 ActionBar 的高度?【英文标题】:How to get the ActionBar height? 【发布时间】:2012-09-06 13:45:03 【问题描述】:

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

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

当第一次创建活动时,我可以在onCreateOptionsMenu回调中调用getHeight()。但是这个方法之后不会被调用。

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

【问题讨论】:

【参考方案1】:

如果您想明确控制 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)

【讨论】:

帮助很大!!但是从哪里可以找到所有这些东西! 通常来自详尽的谷歌搜索或通过开发人员手册苦苦挣扎。我认为在这种情况下是后者,但已经有一段时间了。 我们可以只为特定活动更改操作栏大小吗? "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”等。 androidx.appcompat.R.attr.actionBarSize for androidx【参考方案2】:

在 XML 中,你应该使用这个属性:

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

【讨论】:

如果您使用 ActionBarCompat "@dimen/abc_action_bar_default_height" 感谢阿里 AlNoaimi!在 AppCompat v21 中,名称已更改为:“@dimen/abc_action_bar_default_height_material” 正如下面@muzikant所说,对于appcompat,如果要在代码中使用,正确的属性是android.support.v7.appcompat.R.attr.actionBarSize。如果你想在布局 xml 中使用它,android:paddingTop="?attr/actionBarSize"。在任何地方都可以正常工作。 当您使用自定义 XML 框架布局时,此解决方案非常棒。 如果我想使用这个属性,但如果我想使用负填充,则使用负填充。我该怎么做?【参考方案3】:

好的,我在谷歌上搜索了好几次这篇文章,所以我认为不仅为 Sherlock 描述,也为 appcompat 描述它会很好:

使用 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",将重叠设置为视图/操作栏,甚至使用自定义主题固定操作栏高度,但没有任何效果。原来是这样的:

不幸的是,我发现使用上述方法我只能得到一半的高度(我假设选项栏没有到位)所以要完全解决我需要 double 操作栏的问题高度,一切似乎都很好:

如果有人知道更好的解决方案(比将 actionBarHeight 加倍),我会很高兴告诉我,因为我来自 ios 开发,我发现 Android 视图的大部分内容都非常令人困惑 :)

问候,

hris.to

【讨论】:

我在使用标签时遇到了同样的事情。问题是有时很难检测标签与没有标签,因为某些设备在某些情况下会在视觉上将标签折叠到基本 ActionBar 中。所以对我有用的只是ActionBar.getHeight()。根据具体情况,这也可能对您有用。 我遇到了这个问题,因为我只考虑操作栏的高度,然后我也添加了“通知栏”的高度。对我来说效果很好。 您使用 FrameLayout 并拥有layout_gravity="center_vertical"?将其更改为"bottom"。 Android 2.3 在 FrameLaoyut 中处理边距的方式与较新的 android 不同。【参考方案4】:

@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 版本出现运行时错误。 对我来说,com.actionbarsherlock.R.attr.actionBarSize 适用于 Android 2.3 和 4.0,因此无论 Android 版本如何,您都可以使用它。【参考方案5】:

我认为最安全的方法是:

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;

【讨论】:

如果您使用的是 appcompat,请添加以下内容:else if (true == getTheme().resolveAttribute( android.support.v7.appcompat.R.attr.actionBarSize, tv, true)) actionBarHeight = TypedValue.complexToDimensionPixelSize( tv.data,getResources().getDisplayMetrics()); "if (true== " ? 我想你可以去掉 "true"... :) 是的,你是对的......这是为了清楚起见而添加的 从您的代码看来,如果我使用 ABS 并不重要,在 HONEYCOMB 以上的所有版本中,它都会从 android.R.attr.actionBarSize 获取操作栏高度。这是正确的吗? 是不是还是要指定半个动作栏来隐藏屏幕顶部?***.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"

【讨论】:

请注意横向模式下操作栏的高度较小。 我不建议这样做,因为 actionBarSherlock 在决定操作栏高度时会考虑很多因素。如果您这样做,actionBar 的高度将不会基于设备规格,因此看起来不会像某些设备的标准高度。【参考方案7】:

如果您使用 Toolbar 作为 ActionBar,

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

然后只需使用工具栏的 layout_height 即可。

int actionBarHeight = toolbar.getLayoutParams().height;

【讨论】:

【参考方案8】:

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

【讨论】:

【参考方案9】:

如果您使用的是 Xamarin/C#,这是您要查找的代码:

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

【讨论】:

【参考方案10】:

你可以使用这个函数来获取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;

【讨论】:

【参考方案11】:

满足最流行答案的现成方法:

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;

【讨论】:

【参考方案12】:

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

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

【讨论】:

【参考方案13】:

这个辅助方法应该对某人派上用场。示例: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();
        
    

【讨论】:

【参考方案14】:

你只需要添加这个。

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;
    

【讨论】:

【参考方案15】:

我找到了一种更通用的方法来发现它:

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

其中 'ma​​inView' 是布局的根视图。

这个想法基本上是获取 ma​​inView 的 Y 位置,因为它设置在 ActionBar(或 Toolbar)的正下方。

【讨论】:

【参考方案16】:

操作栏高度根据应用的主题而有所不同。 如果您使用的是 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));
    

【讨论】:

【参考方案17】:

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

【讨论】:

【参考方案18】:
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();

【讨论】:

【参考方案19】:

找到actionbar高度的简单方法是从ActivityonPrepareOptionMenu方法。

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

【讨论】:

【参考方案20】:

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

...并取其更改为的最新值。获取高度。

【讨论】:

【参考方案21】:

在尝试了所有方法都没有成功后,我偶然发现了一种获得操作栏默认高度的实用且非常简单的方法。

仅在 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);

【讨论】:

以上是关于如何获得 ActionBar 的高度?的主要内容,如果未能解决你的问题,请参考以下文章

Android-如何在ActionBar中实现“赞”按钮

是否可以使 ActionBar 选项卡的高度高于 ActionBar 的高度?如果是这样,怎么做?

如何在ActionBar(Android)中添加按钮?

如何优雅的管理ActionBar

ActionBar 徽标居中,Action 项目位于两侧

Action Bar