Search code examples
androidandroid-actionbarandroid-custom-view

Customizing the Android action bar


I'm trying to customize the action bar of my app, but I can't do it correctly and I don't know why.

I have defined my themes.xml like this:

    <?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:actionBarStyle">@style/ActionBar.Solid.Example</item>
    </style>

    <style name = "ActionBar.Solid.Example" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
        <item name="android:background">@drawable/ab_solid_example</item>
    </style>
</resources>

The AndroidManifest.xml where we call the style is:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="coursera.momaproject" >

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Supposedly, we have to see the action bar background in purple color, but what we have is an action bar with her background in black

enter image description here

What happened? What am I doing wrong?


If I remove android:theme="@style/AppTheme" from my AndroidManifest.xml and I add getActionBar().setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.background_alert))); on onCreate() method I've got the next error:

02-10 12:50:56.458    2512-2512/coursera.momaproject E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{coursera.momaproject/coursera.momaproject.MainActivity}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
            at android.support.v7.app.ActionBarActivityDelegate.onCreate(ActionBarActivityDelegate.java:151)
            at android.support.v7.app.ActionBarActivityDelegateBase.onCreate(ActionBarActivityDelegateBase.java:138)
            at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:123)
            at coursera.momaproject.MainActivity.onCreate(MainActivity.java:41)
            at android.app.Activity.performCreate(Activity.java:5133)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)

If I restore my AndroidManifest.xml and remove the actionBar customization, my app gives me an error when I run it.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="coursera.momaproject" >

    <uses-sdk
        android:minSdkVersion="13"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Themes.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

    </style>
</resources>

I've got this error:

02-10 13:42:33.955    2574-2574/coursera.momaproject E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{coursera.momaproject/coursera.momaproject.MainActivity}: java.lang.NullPointerException
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at coursera.momaproject.MainActivity.onCreate(MainActivity.java:44)
            at android.app.Activity.performCreate(Activity.java:5133)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)

onCreate() method, with ** line where it produces the error ...

   protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        **getActionBar().setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.background_alert)));**

        //We add the footer view
        LinearLayout container = (LinearLayout)findViewById(R.id.container);
        View seekBarView = getLayoutInflater().inflate(R.layout.footer_view, null);
        container.addView(seekBarView);

        topLeft = (TextView)findViewById(R.id.topLeft);
        bottomLeft = (TextView)findViewById(R.id.bottomLeft);
        topRight = (TextView)findViewById(R.id.topRight);
        bottomRight = (TextView)findViewById(R.id.bottomRight);

        SeekBar seekBar = (SeekBar)findViewById(R.id.slider);
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                Integer newColor = progressColor(progress, ORIGIN_TOP_LEFT_COLOR, TARGET_TOP_LEFT_COLOR);
                topLeft.setBackgroundColor(newColor.intValue());

                newColor = progressColor(progress, ORIGIN_BOTTOM_LEFT_COLOR, TARGET_BOTTOM_LEFT_COLOR);
                bottomLeft.setBackgroundColor(newColor.intValue());

                newColor = progressColor(progress, ORIGIN_TOP_RIGHT_COLOR, TARGET_TOP_RIGHT_COLOR);
                topRight.setBackgroundColor(newColor.intValue());

                newColor = progressColor(progress, ORIGIN_BOTTOM_RIGHT_COLOR, TARGET_BOTTOM_RIGHT_COLOR);
                bottomRight.setBackgroundColor(newColor.intValue());
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                //We don't do anything

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                //We don't do anything
            }
        });

    }

My file structure is ...

enter image description here


Solution

  • If your minSdkVersion is 11 or higher then write

    getActionBar().setBackgroundDrawable(new ColorDrawable("COLOR"));
    

    in your .class file's onCreate() method.

    Now your class should look like,

    Class MyActivity extends Activity{
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout_activity);
    
            getActionBar().setBackgroundDrawable(new ColorDrawable("YourColor"));
        }
    }