【问题标题】:Adding an action bar to Theme.Black.NoTitleBar Android向 Theme.Black.NoTitleBar Android 添加操作栏
【发布时间】:2012-07-08 01:05:18
【问题描述】:

我正在尝试以编程方式添加操作栏,如 dev documentaion 中所示,但我遇到了一个错误。我的 minSdk 设置为 11,我的应用程序有一个布局和一个活动,活动中唯一的代码是:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.inbox);
    ActionBar actionBar = getActionBar();
    actionBar.show();

}

如果我去掉最后两行,那么我的应用就会运行。我知道全息主题自动包含操作栏,但我不喜欢editTextviews。关于为什么会发生这种情况的任何想法。我应该使用HoloTheme 并以不同的方式为视图设置主题吗?

同样,我在 Eclipse 中没有收到任何错误。我的程序崩溃了,因为我可以从 logcat 中破译为空指针异常。

【问题讨论】:

    标签: android android-layout android-actionbar android-theme


    【解决方案1】:

    来自您链接到的文档:

    如果您有一个自定义活动主题,您想在其中删除操作栏,请将android:windowActionBar 样式属性设置为false。但是,如果您使用主题删除操作栏,则窗口将根本不允许操作栏,因此您以后无法添加它 - 调用 getActionBar() 将返回 null

    由于您使用的是没有操作栏的主题,getACtionBar() 将返回 null,然后您尝试在该 null 上调用 show(),导致抛出异常。

    这样就解释了您遇到的错误。至于如何处理,documentation for ActionBar 说:

    从 Android 3.0(API 级别 11)开始,当 Activity 使用系统的 Holo 主题(或其后代主题之一)(这是默认设置)时,操作栏会出现在 Activity 窗口的顶部。您也可以通过调用requestFeature(FEATURE_ACTION_BAR) 或通过在具有windowActionBar 属性的自定义主题中声明它来添加操作栏。

    这为您提供了两个简单的选项,即在不使用 Holo 主题的情况下拥有 ActionBar。在您的情况下,这可能是最简单的:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_ACTION_BAR); // Add this line
        setContentView(R.layout.inbox);
        ActionBar actionBar = getActionBar();
        actionBar.show();
    }
    

    更新:您还应该只切换到不带 NoTitleBar 部分的 Theme.Black,因为这会阻止 ActionBar 工作。

    【讨论】:

    • 所以我必须将actionBar添加到主题本身?感谢您解释错误
    • @EGHDK 我刚刚更新了我的答案以解释“如何处理它”部分。
    • 我的应用程序仍然崩溃。似乎仍然在 logcat 中获得了 nullPointer。
    • 我不确定如何正确阅读 logcat,所以我不知道如何找到它。对不起。不过我猜你会的!
    • @EGHDK Logcat 会显示一个行号。在这种情况下,我意识到另一个问题是什么,并(再次)更新了我的答案。
    【解决方案2】:

    我遇到了同样的问题。我最终想出了一个合理的解决方案。我有一个最小 api 版本 8,目标 api 为 11。我也不喜欢全息样式,所以我覆盖了如下样式:

    首先,您必须创建一个“res/values-v11”文件夹。您可能已经有一个“values”文件夹,只需在同一级别创建一个“values-v11”(无论您的目标 API 级别是什么......远离使用“values-v11”)。

    创建后,您将在每个文件夹中创建一个包含您的主题的 XML 文档。原始值文件夹将用于低于 android 3.0 (

    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:android="http://schemas.android.com/apk/res/android">
    
        <style name="Theme.Black.OptionalActionBar" parent="@android:style/Theme.Black.NoTitleBar">
            <item name="android:windowNoTitle">True</item>
            <item name="android:windowActionBar">False</item>
        </style>
    
        <style name="OptionalVisibility">
            <item name="android:visibility">visible</item>
        </style>
    
    </resources>
    

    请注意,我没有使用 Holo 主题,而是使用 Theme.Black.NoTitleBar 主题作为父主题。从那里,我设置选项以隐藏低于 api 11 的窗口标题和操作栏。

    然后,我在“values-v11”文件夹中创建第二个主题文档,并设置如下:

    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:android="http://schemas.android.com/apk/res/android">
    
        <style name="Theme.Black.OptionalActionBar" parent="@android:style/Theme.Black.NoTitleBar">
            <item name="android:windowNoTitle">false</item>
            <item name="android:windowActionBar">true</item>
            <item name="android:actionBarStyle">@android:style/Widget.Holo.ActionBar</item>
        </style>
    
        <style name="OptionalVisibility">
            <item name="android:visibility">invisible</item>
            <item name="android:height">1dp</item>
        </style>
    
    </resources>
    

    在上述主题中,它启用操作栏并将其设置为 Holo 主题,但保留所有其他元素。所以操作栏看起来像“holo”-ish,但其他所有内容都与低版本中显示的完全相同(而且我没有看到 Holo 附带的丑陋文本条目)。

    然后在清单中,如果我想显示操作栏,我只需将该活动的主题设置为android:theme="@style/Theme.Black.OptionalActionBar"

    我之所以这样做,是因为我依赖现已弃用的硬件菜单按钮在布局上失败了。使用上面的主题,如果需要,我可以设置操作栏,如果是旧设备,我可以将其保留为菜单。然后,我所要做的就是在我的菜单创建方法上设置一个属性,以无缝支持 2.0 到 4.0。

    无论如何,看看这是否能让你到达你需要的地方。

    在我看来,它比其他方法容易得多,因为您不必记住请求操作栏或在代码中执行任何操作。您只需将您的主题设置为您的活动......然后就可以开始了。

    【讨论】:

    • 正是我想要的。这应该是标记的答案
    【解决方案3】:

    达山说什么……有点

    更进一步,我会查看 ActionBarSherlock,结合支持库,您可以将操作栏添加到几乎任何 2.x+ 版本的 android

    要获得全屏/无标题栏,您可以从类似于 ABS 主题之一创建自己的主题

    <style name="Theme.MY.Sherlock.Fullscreen" parent="Theme.Sherlock.Light.DarkActionBar">
            <item name="android:windowFullscreen">true</item>;
     </style>
    

    在你的 onCreate 中应用该主题,然后让操作栏显示是相同的(除了你会使用 ABS 支持前缀)所以基本上

    setTheme(R.style.Theme_MY_Sherlock_Fullscreen);
    setContentView(R.layout.mylayout);
    getSupportActionBar.Show();
    

    我假设您可以对标准操作栏执行相同操作(使用全息主题作为基础),因为 ABS 几乎是一个重复的功能(而且大部分源代码,ABS 主要是一个包装类)它甚至检测并使用 14 及更高版本的本机实现(11 及中间有一些缺失的功能/修复)

    你可以看看ABS here,好像他刚刚更新到JB了

    -- 在 values 下的资源文件夹中创建一个主题.xml 文件 ( /res/values/themes.xml )

    然后将它放在那里并尝试上述方法,但当然在 setTheme( 将名称替换为 Theme_My_Holo_FullScreen 并且不要使用 getSupportActionbar(). 前缀,我从不费心使用本机实现,但它应该工作相同。

    <?xml version="1.0" encoding="utf-8"?>
    
    <resources>
    
        <style name="Theme.My.Holo.Fullscreen" parent="Theme.Holo">
            <item name="android:windowFullscreen">true</item>;
        </style>
    
    </resources>
    

    【讨论】:

    • 是的,我计划稍后实施 ABS,但我对如何无法使用 Theme.Black.noTitleBar 为 API 11 级及更高版本实施操作栏感到困惑。不过我仍在学习样式,所以你做的第一个代码注释对我来说没有意义 =) 样式标签去哪里了?
    • Styles go in /res/values/themes.xml 我会在上面放一个完整的文件片段-standby
    • 谢谢。这对我以后有很大帮助。我很感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    相关资源
    最近更新 更多