PrimaryDark在安卓中未设置状态栏颜色

3

我创建了一个应用程序,它有多个主题并可以动态更改。也就是说,在运行时用户可以选择不同的主题,以便UI组件颜色在运行时更改。然而,我遇到了一个奇怪的问题。问题是状态栏颜色不会随着主题的更改而改变。状态栏始终保持初始主题颜色。

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-color。它总是采用默认主题(启动主题)的颜色。

1个回答

7

通过setTheme(int resId)方法在onCreate()中设置主题对StatusBar没有任何影响,因为它不是Activity本身的一部分(据我所知)。

所以为了实现所需的效果,你需要编写程序来完成。以下是一个代码片段,如果SDK版本大于21,则解析R.attr.colorPrimaryDark并将其设置为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设置的颜色。因此,如果您正在使用导航抽屉并且希望抽屉栏位于状态栏下面,您必须在抽屉被打开时手动将状态栏颜色设置为透明:

示例

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

非常感谢您的回答。但是,当我打开导航抽屉时,我的应用程序状态栏并没有变得透明,尽管我在每个主题中都设置了此属性 <item name="android:statusBarColor">@android:color/transparent</item>。 - Pruthviraj
@Android_developer 哦,是的 - 该属性被 setStatusBarColor(int color) 方法覆盖了。请参见我的编辑以获取解决方法。 - reVerse
谢谢,这帮助我解决了导航抽屉的问题! :) - box

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接