如何获得动作栏的高度?

我试图获得ActionBar的高度(使用夏洛克)每次创建一个活动(特别处理旋转配置变化,其中动作栏的高度可能会改变)。

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

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

所以我的问题是什么时候我可以调用getHeight(),并确保它不返回0? 或者如果不可能,我如何设置动作栏的高度
190474 次浏览

要设置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"

虽然@bird的答案是一个选项,如果你想显式地控制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)
}

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

我认为最安全的方法是:

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

从Activity onPrepareOptionMenu方法中找到动作栏高度的一个简单方法。

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

好吧,我在谷歌上搜索了几次,找到了这个帖子,所以我认为不仅是对夏洛克的描述,对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());
}

三明治前问题

我需要操作栏的高度,因为在pre ICE_CREAM_SANDWITCH设备上,我的视图是重叠的操作栏。我试着设置android:layout_marginTop="?android: attr / actionBarSize”,android: layout_marginTop = "吗?attr/actionBarSize”,设置重叠关闭查看/动作栏,甚至固定的动作栏高度与自定义主题,但没有工作。它看起来是这样的:

重叠问题

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

overlap fixed

如果有人知道更好的解决方案(比加倍actionBarHeight),我很高兴让我知道,因为我来自iOS开发,我发现大多数Android视图的东西相当混乱:)

问候,

hris.to

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

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

这个助手方法对某些人来说应该会派上用场。例如: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();
}
}
}

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

你只需要加上这个。

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

如果你正在使用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'是布局的根视图。

这个想法基本上是获得mainView的Y位置,因为它被设置在动作栏(或工具栏)的正下方。

你可以使用这个函数来获取动作栏的高度。

public int getActionBarHeight() {
final TypedArray ta = getContext().getTheme().obtainStyledAttributes(
new int[] {android.R.attr.actionBarSize});
int actionBarHeight = (int) ta.getDimension(0, 0);
return actionBarHeight;
}
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();
}
操作栏的高度根据应用的主题而不同。 如果你正在使用AppCompatActivity,在大多数情况下,高度将不同于正常的Activity

如果你使用AppCompatActivity,你应该使用r.t r. actionbarsize而不是android. r.t r. 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));
}

如果您使用工具栏作为动作栏,

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

然后使用工具栏的layout_height。

int actionBarHeight = toolbar.getLayoutParams().height;

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

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

一个现成的方法来完成最流行的答案:

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

以下是我使用的Kotlin的更新版本,假设phone比Honeycomb更高:

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