Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding an action bar to Theme.Black.NoTitleBar Android

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.

like image 478
EGHDK Avatar asked Nov 27 '22 11:11

EGHDK


2 Answers

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.

like image 139
Darshan Rivka Whittle Avatar answered Dec 09 '22 19:12

Darshan Rivka Whittle


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.

like image 23
Michael Stoner Avatar answered Dec 09 '22 18:12

Michael Stoner