PrimaryDark doesn't set color of StatusBar in android

I created an app and has multiple themes and it changes dynamically. I mean, at runtime, the user can select different themes. so that the color of the UI components changes at runtime. I am stuck with a strange problem. The problem is that the color of the status bar doesn't change to match the theme. statusBar always remains in the original theme color.

values-v21 / style.xml below

    <style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="colorPrimary">@color/primary</item>
        <item name="colorPrimaryDark">@color/primary_dark</item>
        <item name="colorAccent">@color/accent</item>
        <item name="android:textColorPrimary">@color/primary_text</item>
        <item name="android:icon">@color/icons</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

values-v21/themes.xml is as below
===================================

<resources>    
    <style name="AppThemeRed" parent="Theme.AppCompat.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">#F44336</item>
        <item name="colorPrimaryDark">#D32F2F</item>
        <item name="colorAccent">#FFCDD2</item>
        <item name="android:textColorPrimary">#FFFFFF</item>
        <item name="android:icon">@color/icons</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

    <style name="AppThemeAmber" parent="Theme.AppCompat.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">#FFC107</item>
        <item name="colorPrimaryDark">#FFA000</item>
        <item name="colorAccent">#FFEB3B</item>
        <item name="android:textColorPrimary">#FFFFFF</item>
        <item name="android:icon">@color/icons</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

    <style name="AppThemeBlue" parent="Theme.AppCompat.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">#3F51B5</item>
        <item name="colorPrimaryDark">#303F9F</item>
        <item name="colorAccent">#448AFF</item>
        <item name="android:textColorPrimary">#FFFFFF</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

    <style name="AppThemePurple" parent="Theme.AppCompat.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">#9C27B0</item>
        <item name="colorPrimaryDark">#7B1FA2</item>
        <item name="colorAccent">#7C4DFF</item>
        <item name="android:textColorPrimary">#FFFFFF</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>

    <style name="AppThemeYellow" parent="Theme.AppCompat.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">#FFEB3B</item>
        <item name="colorPrimaryDark">#FBC02D</item>
        <item name="colorAccent">#CDDC39</item>
        <item name="android:textColorPrimary">#FFFFFF</item>
        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
        <item name="android:statusBarColor">@android:color/transparent</item>
    </style>
</resources>

      

when the user selects a theme from the theme picker dialog, I call the function and set the theme for that activity, and also recreate the activity.

public static void onActivityCreateSetTheme(Activity activity)
    {
        switch (sTheme)
        {
            case 0:
                activity.setTheme(R.style.AppThemeRed);
                break;

            case 1:
                activity.setTheme(R.style.AppThemeAmber);
                break;

            default:
            case 2:
                activity.setTheme(R.style.AppTheme);
                break;

            case 3:
                activity.setTheme(R.style.AppThemeBlue);
                break;

            case 4:
                activity.setTheme(R.style.AppThemePurple);
                break;

            case 5:
                activity.setTheme(R.style.AppThemeYellow);
                break;

        }
    }

      

I am using NavigationView on a drawer and the drawer goes below the status bar, no problem. But the status bar doesn't bring up the current primaryDark-color topic. It always only accepts the default theme color (launcher theme).

+3


source to share


1 answer


Setting up the theme with a help setTheme(int resId)

in the method onCreate()

will not have any effect on the StatusBar since it is not part of the Activity itself afaik.

So, to achieve the desired effect, you need to do it programmatically. Here is a snippet that resolves R.attr.colorPrimaryDark

and sets it for the StatusBar if the SDK level is above 21:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    init();
    setContentView(R.layout.activity_management);
    // Further code
}

private void init(){
    // Set the Theme
    setTheme(R.style.MyAppTheme);
    if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
        getWindow().setStatusBarColor(getAttributeColor(R.attr.colorPrimaryDark));
    }
}

// Resolve the given attribute of the current theme
private int getAttributeColor(int resId) {
    TypedValue typedValue = new TypedValue();
    getTheme().resolveAttribute(resId, typedValue, true);
    int color = 0x000000;
    if (typedValue.type >= TypedValue.TYPE_FIRST_COLOR_INT && typedValue.type <= TypedValue.TYPE_LAST_COLOR_INT) {
        // resId is a color
        color = typedValue.data;
    } else {
        // resId is not a color
    }
    return color;
}

      

Edit



This approach explicitly overwrites the color that is set through android:statusBarColor

. Therefore, if you are using the NavigationDrawer and want the drawer under the "StatusBar", you have to set the color of the StatusBar to transparent manually as soon as the drawer is opened:

Example

actionBarDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar,
            R.string.open_drawer_accessibility_desc,
            R.string.close_drawer_accessibility_desc) {

        @SuppressLint("NewApi")
        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
            super.onDrawerSlide(drawerView, slideOffset);
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                getWindow().setStatusBarColor(
                        getResources().getColor(android.R.color.transparent));
            }
        }

        /** Called when a drawer has settled in a completely open state. */
        @Override
        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
        }

        /** Called when a drawer has settled in a completely closed state. */
        @Override
        public void onDrawerClosed(View view) {
            super.onDrawerClosed(view);
        }
    };
}

      

+6


source







All Articles