在Android JellyBean上更改Actionbar高度

时间:2021-03-30 18:24:16

I've been recently developing an Android app, in which i need to have a custom layout and dimension for the tab bar. The way that i did it until now is by using Jake Wharton's ActionBarSherlock library to support pre-HoneyComb Android versions, and by applying a style to the app in which i edit the actionBarSize style item.

我最近一直在开发一个Android应用程序,我需要为标签栏设置自定义布局和尺寸。我到目前为止的方式是使用Jake Wharton的ActionBarSherlock库来支持pre-HoneyComb Android版本,并通过将样式应用于我编辑actionBarSize样式项的应用程序。

Now, I've been testing the app on the Galaxy S3 (with Jellybean on it), and the tab bar height doesn't change anymore according to the actionBarSize value.

现在,我一直在测试Galaxy S3上的应用程序(上面有Jellybean),并且根据actionBarSize值,标签栏高度不再变化。

So I've started looking through JellyBean's code, and I found this method in the ActionBarPolicy class:

所以我开始查看JellyBean的代码,我在ActionBarPolicy类中找到了这个方法:

    public int getTabContainerHeight() {
            TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.ActionBar,
               com.android.internal.R.attr.actionBarStyle, 0);
            int height = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
            Resources r = mContext.getResources();
            if (!hasEmbeddedTabs()) {
                // Stacked tabs; limit the height
                height = Math.min(height,
                        r.getDimensionPixelSize(R.dimen.action_bar_stacked_max_height));
            }
            a.recycle();
            return height;
    }

From what i gather in this method, it seems that JellyBean limits the height of the TabBar, when the app is in portrait mode, by setting the tab bar height to the "action_bar_stacked_max_height" dimension value (which is 48dp, in 4.1's /values/dimen.xml file), even though I've set the action bar height in actionBarSize.

从我在这个方法中收集的内容来看,似乎JellyBean限制TabBar的高度,当应用程序处于纵向模式时,通过将标签栏高度设置为“action_bar_stacked_max_height”维度值(48dp,在4.1的/ values / dimen.xml文件),即使我在actionBarSize中设置了操作栏高度。

I've tried overriding this dimension value, by setting it to my own value in my own dimen.xml file, but i had no luck. It didn't work.

我已经尝试覆盖这个维度值,通过在我自己的dimen.xml文件中将其设置为我自己的值,但我没有运气。它没用。

My question:

Do you guys know of a way in which i can override the"action_bar_stacked_max_height" dimen value?

你们知道我可以覆盖“action_bar_stacked_max_height”维度值的方法吗?

Thank you in advance!

先感谢您!

3 个解决方案

#1


1  

it seems to me that it was done on purpose and I don't know why. There are some variables in bools.xml

在我看来,这是故意的,我不知道为什么。 bools.xml中有一些变量

<bool name="action_bar_embed_tabs">true</bool>
<bool name="action_bar_embed_tabs_pre_jb">false</bool>

The height of embed tabs is limited to 48dip in ActionBarPolicy.java, as you have already mentioned. That's why such behaviour can be seen only in Android JellyBean or higher. I can't find a better solution than to make some java reflection. So here is the code

正如您已经提到的,在ActionBarPolicy.java中,嵌入标签的高度限制为48dip。这就是为什么只能在Android JellyBean或更高版本中看到这种行为的原因。我找不到比做一些java反射更好的解决方案。所以这是代码

private void hackJBPolicy() {
    View container = findScrollingTabContainer();
    if (container == null) return;

    try {
        int height = getResources().getDimensionPixelSize(R.dimen.action_bar_height);
        Method method = container.getClass()
                .getDeclaredMethod("setContentHeight", Integer.TYPE);
        method.invoke(container, height);
    } catch (NoSuchMethodException e) {
        Log.e(LOG_TAG, e.getLocalizedMessage(), e);
    } catch (IllegalArgumentException e) {
        Log.e(LOG_TAG, e.getLocalizedMessage(), e);
    } catch (IllegalAccessException e) {
        Log.e(LOG_TAG, e.getLocalizedMessage(), e);
    } catch (InvocationTargetException e) {
        Log.e(LOG_TAG, e.getLocalizedMessage(), e);
    }
}

private View findScrollingTabContainer() {
    View decor = getWindow().getDecorView();
    int containerId = getResources().getIdentifier("action_bar_container", "id", "android");

    // check if appcompat library is used
    if (containerId == 0) {
        containerId = R.id.action_bar_container;
    }

    FrameLayout container = (FrameLayout) decor.findViewById(containerId);

    for (int i = 0; i < container.getChildCount(); i++) {
        View scrolling = container.getChildAt(container.getChildCount() - 1);
        String simpleName = scrolling.getClass().getSimpleName(); 
        if (simpleName.equals("ScrollingTabContainerView")) return scrolling;
    }

    return null;
}

Use the method hackJBPolicy() in your onCreate. Notice that I used ActionBar from appcompat library. Here is the link to the sample project with the use of this workaround.

在onCreate中使用hackJBPolicy()方法。请注意,我使用了appcompat库中的ActionBar。以下是使用此变通方法的示例项目的链接。

After all, it seems to me that it would be easier in future to create custom view aligned to the top of the screen instead of using ActionBar in tabs mode if your ui design is a bit far from guidlines.

毕竟,在我看来,如果您的ui设计与guidlines有点远,将来更容易创建与屏幕顶部对齐的自定义视图,而不是在标签模式下使用ActionBar。

#2


26  

Try putting android:actionBarSize and actionBarSize under the Theme you are using, like so:

尝试将android:actionBarSize和actionBarSize放在您正在使用的主题下,如下所示:

<style name="Theme.white_style" parent="@android:style/Theme.Holo.Light.DarkActionBar">
        <item name="android:actionBarSize">55dp</item>
        <item name="actionBarSize">55dp</item>
</style> 

#3


9  

Try using android:height like the following:

尝试使用android:height,如下所示:

<style name="AppActionBar">
    <item name="android:height">50dp</item>
</style>

<style name="MainActivityStyle" parent="@android:style/Theme.Holo">
    <item name="android:actionBarStyle">@style/AppActionBar</item>
</style>

#1


1  

it seems to me that it was done on purpose and I don't know why. There are some variables in bools.xml

在我看来,这是故意的,我不知道为什么。 bools.xml中有一些变量

<bool name="action_bar_embed_tabs">true</bool>
<bool name="action_bar_embed_tabs_pre_jb">false</bool>

The height of embed tabs is limited to 48dip in ActionBarPolicy.java, as you have already mentioned. That's why such behaviour can be seen only in Android JellyBean or higher. I can't find a better solution than to make some java reflection. So here is the code

正如您已经提到的,在ActionBarPolicy.java中,嵌入标签的高度限制为48dip。这就是为什么只能在Android JellyBean或更高版本中看到这种行为的原因。我找不到比做一些java反射更好的解决方案。所以这是代码

private void hackJBPolicy() {
    View container = findScrollingTabContainer();
    if (container == null) return;

    try {
        int height = getResources().getDimensionPixelSize(R.dimen.action_bar_height);
        Method method = container.getClass()
                .getDeclaredMethod("setContentHeight", Integer.TYPE);
        method.invoke(container, height);
    } catch (NoSuchMethodException e) {
        Log.e(LOG_TAG, e.getLocalizedMessage(), e);
    } catch (IllegalArgumentException e) {
        Log.e(LOG_TAG, e.getLocalizedMessage(), e);
    } catch (IllegalAccessException e) {
        Log.e(LOG_TAG, e.getLocalizedMessage(), e);
    } catch (InvocationTargetException e) {
        Log.e(LOG_TAG, e.getLocalizedMessage(), e);
    }
}

private View findScrollingTabContainer() {
    View decor = getWindow().getDecorView();
    int containerId = getResources().getIdentifier("action_bar_container", "id", "android");

    // check if appcompat library is used
    if (containerId == 0) {
        containerId = R.id.action_bar_container;
    }

    FrameLayout container = (FrameLayout) decor.findViewById(containerId);

    for (int i = 0; i < container.getChildCount(); i++) {
        View scrolling = container.getChildAt(container.getChildCount() - 1);
        String simpleName = scrolling.getClass().getSimpleName(); 
        if (simpleName.equals("ScrollingTabContainerView")) return scrolling;
    }

    return null;
}

Use the method hackJBPolicy() in your onCreate. Notice that I used ActionBar from appcompat library. Here is the link to the sample project with the use of this workaround.

在onCreate中使用hackJBPolicy()方法。请注意,我使用了appcompat库中的ActionBar。以下是使用此变通方法的示例项目的链接。

After all, it seems to me that it would be easier in future to create custom view aligned to the top of the screen instead of using ActionBar in tabs mode if your ui design is a bit far from guidlines.

毕竟,在我看来,如果您的ui设计与guidlines有点远,将来更容易创建与屏幕顶部对齐的自定义视图,而不是在标签模式下使用ActionBar。

#2


26  

Try putting android:actionBarSize and actionBarSize under the Theme you are using, like so:

尝试将android:actionBarSize和actionBarSize放在您正在使用的主题下,如下所示:

<style name="Theme.white_style" parent="@android:style/Theme.Holo.Light.DarkActionBar">
        <item name="android:actionBarSize">55dp</item>
        <item name="actionBarSize">55dp</item>
</style> 

#3


9  

Try using android:height like the following:

尝试使用android:height,如下所示:

<style name="AppActionBar">
    <item name="android:height">50dp</item>
</style>

<style name="MainActivityStyle" parent="@android:style/Theme.Holo">
    <item name="android:actionBarStyle">@style/AppActionBar</item>
</style>