Adding an action bar to Theme.Black.NoTitleBar Android

26,095

Solution 1

From the documentation you linked to:

If you have a custom activity theme in which you'd like to remove the action bar, set the android:windowActionBar style property to false. However, if you remove the action bar using a theme, then the window will not allow the action bar at all, so you cannot add it later—calling getActionBar() will return null.

Since you're using a theme without an action bar, getACtionBar() is returning null, and then you're attempting to call show() on that null, resulting in an Exception being thrown.

So that explains the error you're getting. As far as what to do about it, the documentation for ActionBar says:

Beginning with Android 3.0 (API level 11), the action bar appears at the top of an activity's window when the activity uses the system's Holo theme (or one of its descendant themes), which is the default. You may otherwise add the action bar by calling requestFeature(FEATURE_ACTION_BAR) or by declaring it in a custom theme with the windowActionBar property.

That gives you two easy options to have an ActionBar without using a Holo theme. This is probably simplest in your case:

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

Update: You should also switch to just Theme.Black without the NoTitleBar part, as that prevents the ActionBar from working.

Solution 2

I ran into the same problem. I eventually came up with a reasonable solution. I have a min api version 8 with a target api of 11. I don't like the holo styles either so I override the styles like the following:

First, you have to create a "res/values-v11" folder. You probably already have a "values" folder, just create a "values-v11" at the same level (doesn't matter what your target API level is...aways use "values-v11").

Once that is created, you create an XML document containing your theme in each of the folders. The original values folder will be used for anything less than android 3.0 (< api 11). Your theme would look something like this.

<?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>

Notice that I am NOT using the Holo theme but instead using the Theme.Black.NoTitleBar theme as the parent. From there, I set the options to hide the window title and action bar for things lower than api 11.

Then, I create a second theme document in the "values-v11" folder and set it up like this:

<?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>

In the above theme, it enables the action bar and sets it up with the Holo theme, but leaves all the other elements alone. So the action bar looks "holo"-ish but everything else stays exactly as it appears in the lower versions (and I don't get the ugly text entry that comes with Holo).

Then in the manifest if I want to have the actionbar show up, I just set the theme for that activity to android:theme="@style/Theme.Black.OptionalActionBar"

I did this specifically because I failed on my layouts by relying on the, now deprecated, hardware menu button. With the use of the themes above, I can setup the action bar if it is required or leave it as menus if it is an older device. Then, all I have to do is set a single property on my menu creation methods to support 2.0 through 4.0 seamlessly.

At any rate, take a look and see if this gets you to where you need to be.

In my mind it is a lot easier than the other approaches because you don't have to remember to request the actionbar or do anything in code. You just set your theme on your activity...and off you go.

Solution 3

What Darshan Said ... kind of

To go a little further I would check out ActionBarSherlock, in combination with the support library you can then add the action bar to pretty much any version of android that is 2.x+

To get a full screen / no title bar you would create your own theme from one of the ABS theme's similar to

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

Applying that theme in your onCreate and then getting the action bar to show is the same (except you would use the ABS support prefix ) so basically

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

I am assuming you can do the same for a standard action bar (using the holo theme as a base) since ABS is pretty much a duplicate functionality wise (and much of the source, ABS is mostly a wrapper class) it even detects and then uses the native implementation on 14 and above (11 and in-between has some missing features / fixes )

You can take a look at ABS here and it looks like he just updated it to JB

-- In your resources folder under values create a themes.xml file ( /res/values/themes.xml )

Then put this in there and give the above a try, but of course in setTheme( replace the name with Theme_My_Holo_FullScreen and dont use the getSupportActionbar(). prefix, I never bother using the native implementation but it should work the same.

<?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>
Share:
26,095
EGHDK
Author by

EGHDK

Updated on August 27, 2020

Comments

  • EGHDK
    EGHDK over 3 years

    I'm trying to add the action bar programatically as shown in the dev documentaion but I'm coming across an error. My minSdk is set to 11, my application has one layout and one activity and the only code in the activity is:

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

    If I take out those last two lines then my app runs. I know that the holo theme include the actionbar automatically, but I don't like the editTextviews. Any ideas on why this is happening. Should I be using the HoloTheme and themeing the views differently?

    Again, I'm not getting any errors in eclipse. My program is crashing from what I can decipher from logcat as an null pointer exception.

  • EGHDK
    EGHDK almost 12 years
    So I have to add the actionBar to the theme itself? Thanks for explaining the error though
  • Darshan Rivka Whittle
    Darshan Rivka Whittle almost 12 years
    @EGHDK I just updated my answer to explain the "what to do about it" part.
  • EGHDK
    EGHDK almost 12 years
    Still crashing my application. Still seems to get the nullPointer in logcat.
  • EGHDK
    EGHDK almost 12 years
    I'm not sure how to read logcat to well, so I don't know how to find that out. Sorry. I'm guessing you do though!
  • Darshan Rivka Whittle
    Darshan Rivka Whittle almost 12 years
    @EGHDK The Logcat shows you a line number. In this case I realized what the other issue was and updated my answer (again).
  • EGHDK
    EGHDK almost 12 years
    Yeah, I plan on implementing ABS later on, but I'm flustered at how I can't implement the action bar with Theme.Black.noTitleBar for API lvl 11 and up. I'm still learning styles though so the first code comment you make doesn't make sense to me =) Where do the style tags go?
  • Idistic
    Idistic almost 12 years
    Styles go in /res/values/themes.xml I will put in a whole file fragment above - standby
  • EGHDK
    EGHDK almost 12 years
    Ahh... Yes, now it works. Also, I can't find this "line number" thing in logcat. Where should it be?
  • EGHDK
    EGHDK almost 12 years
    Thanks. This will help me a lot later on. I appreciate it.
  • Darshan Rivka Whittle
    Darshan Rivka Whittle almost 12 years
    @EGHDK The stack trace should show file names and line numbers. If it's not obvious to you, I'm sure a quick web search would reveal some detailed explanations.
  • Marcos Placona
    Marcos Placona over 11 years
    Just what I was looking for. This should be the marked answer