PrimaryDark没有在android中设置StatusBar颜色

时间:2015-06-30 11:44:47

标签: android android-5.0-lollipop android-styles

我创建了一个应用程序,它有多个主题,并且动态变化。我的意思是在运行时用户可以选择不同的主题。以便UI组件在运行时颜色发生变化。我遇到了一个奇怪的问题。问题是状态栏颜色根据主题没有变化。 statusBar始终保持初始主题颜色。

values-v21 / style.xml如下所示

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

当用户从主题选择对话框中选择主题时,我调用一个函数并为该活动设置主题,同时重新创建活动。

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;

        }
    }

我在抽屉中使用NavigationView并且抽屉位于状态栏下面没问题。但状态栏没有获取当前主题的primaryDark颜色。它总是只采用默认主题(启动主题)颜色。

1 个答案:

答案 0 :(得分:6)

setTheme(int resId)方法中通过onCreate()设置主题不会对StatusBar产生任何影响,因为它不属于活动本身的一部分。

因此,为了达到预期的效果,您需要以编程方式进行。这是一个解析R.attr.colorPrimaryDark的代码段,如果SDK级别高于21,则会为StatusBar设置它:

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

修改

这种方法显然会覆盖通过android:statusBarColor设置的颜色。因此,如果您正在使用NavigationDrawer,并且您希望抽屉在&#34;下使用#34; StatusBar必须在打开抽屉后立即手动将StatusBar颜色设置为透明:

示例

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