向Theme.Black.NoTitleBar主题添加操作栏(Android)

4
我正在尝试按照开发文档中所示的方法以编程方式添加操作栏,但我遇到了一个错误。我的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();

}

如果我删除最后两行,我的应用程序就可以运行了。我知道Holo主题会自动包含ActionBar,但我不喜欢editText视图。你有什么想法为什么会发生这种情况吗?我应该使用HoloTheme并以不同的方式对视图进行主题设置吗?
再次说明,在eclipse中没有出现任何错误。从logcat中我可以看出我的程序崩溃了,是一个空指针异常。
3个回答

12

根据您提供的文档:

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

由于您正在使用没有操作栏的主题,因此getActionBar()返回null,然后您正在尝试在该null上调用show(),从而导致抛出异常。

因此,这就解释了您遇到的错误。至于如何解决它,ActionBar文档提供了以下信息:

从Android 3.0(API级别11)开始,在活动使用系统的Holo主题(或其后代主题)时,操作栏将显示在活动窗口的顶部,这是默认设置。否则,您可以通过调用requestFeature(FEATURE_ACTION_BAR)或使用windowActionBar属性在自定义主题中声明它来添加操作栏。

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

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

更新:您还应该切换到仅使用Theme.Black,而不包括NoTitleBar部分,因为这会阻止ActionBar的工作。


所以我必须将actionBar添加到主题本身中吗?谢谢你解释这个错误。 - EGHDK
@EGHDK,我刚刚更新了我的答案,解释了“该怎么做”的部分。 - Darshan Rivka Whittle
仍然崩溃我的应用程序。在logcat中仍然似乎出现了nullPointer。 - EGHDK
@EGHDK,Logcat会显示行号。在这种情况下,我意识到了另一个问题,并更新了我的答案(再次)。 - Darshan Rivka Whittle
啊...是的,现在它可以工作了。另外,在logcat中我找不到这个“行号”东西。它应该在哪里? - EGHDK
显示剩余2条评论

10

我也曾遇到同样的问题。最终,我想出了一个合理的解决方案。我的最小API版本为8,目标API版本为11。我也不喜欢Holo样式,所以我重写了样式,像这样:

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

一旦创建了这个文件夹,就可以在每个文件夹中创建一个包含您的主题的XML文档。原始的values文件夹将用于任何低于Android 3.0(< API 11)的内容。您的主题看起来可能像这样。

<?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”,但其他所有东西看起来仍然与较低版本中的相同(我没有得到Holo所带来的丑陋文本输入)。
然后,在清单中,如果我想让操作栏显示出来,我只需将该活动的主题设置为android:theme="@style/Theme.Black.OptionalActionBar" 我之所以这样做,是因为在我的布局中,我依赖于现在已被弃用的硬件菜单按钮失败了。通过使用上面的主题,如果需要设置操作栏,则可以设置其,否则可以将其作为菜单留在旧设备上。然后,我只需要在我的菜单创建方法上设置一个属性,就可以无缝支持2.0到4.0。
无论如何,请看一看,看看这是否能让你达到需要的目的。
在我看来,这比其他方法容易得多,因为您不必记得请求操作栏或在代码中执行任何操作。只需在您的活动上设置主题...然后就可以了。

1
正是我所需要的。这应该被标记为答案。 - Marcos Placona

7

达尔山所说的...有点

为了更进一步,我建议使用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();

我假设你可以为标准操作栏执行相同操作(以holo主题为基础),因为ABS在功能上几乎是重复的(并且大部分源代码,ABS主要是一个包装类),它甚至会检测然后在14及以上版本上使用本地实现(11和中间版本缺少一些功能/修复)。你可以看一下这里的ABS,看起来他刚刚更新到JB。
- 在资源文件夹下的values文件夹中创建themes.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,但我感到困惑的是,我无法在API lvl 11及以上使用Theme.Black.noTitleBar实现操作栏。不过我仍在学习样式,所以你提出的第一个代码注释对我来说没有意义=)样式标签放在哪里? - EGHDK
样式放在/res/values/themes.xml文件中。我将在上面放入整个文件片段 - 请等待。 - Idistic
谢谢。这会在以后帮助我很多。我非常感激。 - EGHDK

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接