更改 Android JellyBean 上的操作栏高度

Posted

技术标签:

【中文标题】更改 Android JellyBean 上的操作栏高度【英文标题】:Change Actionbar height on Android JellyBean 【发布时间】:2013-02-12 10:34:18 【问题描述】:

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

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

于是我开始翻看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;
    

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

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

我的问题:

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

提前谢谢你!

【问题讨论】:

我也有同样的问题。您对此有什么解决方案吗? 【参考方案1】:

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

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

【讨论】:

嗯,它会改变主操作栏的高度,但不会影响标签栏的高度(绝对不是在 Android 4.2.2 上)。 看到同样的事情。似乎没有改变标签栏的高度。 对我有用,就像一个魅力。 我让它在模拟器上最旧版本的果冻豆上工作【参考方案2】:

尝试使用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>

【讨论】:

适用于拆分操作栏,但不适用于第二行/堆叠栏(选项卡)【参考方案3】:

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

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

正如您已经提到的,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;

onCreate 中使用方法hackJBPolicy()。请注意,我使用了 appcompat 库中的 ActionBar。这是使用此解决方法的示例项目的link。

毕竟,在我看来,如果您的 ui 设计与指导线有点远,那么创建与屏幕顶部对齐的自定义视图而不是在选项卡模式下使用 ActionBar 会更容易。

【讨论】:

您能否解释一下如何使用标准操作栏而不是支持库来实现它?我找不到名为 R.id.action_bar_container 的资源。 我知道这是一个很晚的评论,但我会接受 st_ 的回答,即使它使用反射(理论上会减慢应用程序的速度)。但他提供了足够的信息,以便让一个人破解“JB政策”。最后,正如 st_ 所说,我开发了自己的自定义标签栏。

以上是关于更改 Android JellyBean 上的操作栏高度的主要内容,如果未能解决你的问题,请参考以下文章

JellyBean 在抓图时表现不同

run-as 包 'a.b.c' 未知 - Galaxy S4 Jellybean 或 Android 4.3

JellyBean 4.3 中的 GoogleTTSService 的名称是啥?

Android WebView JellyBean -> 不应该发生:找不到基于矩形的测试节点

有没有办法在 Android JellyBean TimePickerDialog 中使用取消?

Webview shouldOverrideUrlLoading 适用于除 4.1.x jellybean 之外的之前的 android 版本