You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Android全版本中修改状态栏图标颜色?

如何在所有Android版本中将状态栏图标颜色改为自定义色#5DD6D6

Got it, let's break this down. You want to set your status bar icons to the custom color #5DD6D6 across all Android versions, but the official SYSTEM_UI_FLAG_LIGHT_STATUS_BAR only works on API 23+. Here's a comprehensive, version-specific solution that covers every supported Android release:


1. API 23+ (Android 6.0 Marshmallow & Above)

Starting with API 23, we have official hooks to tweak status bar appearance, plus we can use color filters to apply custom hues to the icons (since the default only offers light/dark states).

Code Implementation

fun setCustomStatusBarIconColor(window: Window, targetColor: Int) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        // First, enable light status bar mode to ensure icons aren't locked to white
        window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        
        // Apply custom color filter to all status bar icons
        val decorView = window.decorView
        val resources = decorView.context.resources
        // Target both light and dark icon containers (varies by ROM)
        val iconContainerIds = listOf(
            resources.getIdentifier("statusBarIcons", "id", "android"),
            resources.getIdentifier("statusBarDarkIcons", "id", "android")
        )

        iconContainerIds.forEach { containerId ->
            val container = decorView.findViewById<ViewGroup>(containerId)
            container?.let { group ->
                for (i in 0 until group.childCount) {
                    group.getChildAt(i).drawable?.let { drawable ->
                        // Use DrawableCompat for backward-compatible tinting
                        DrawableCompat.setTint(DrawableCompat.wrap(drawable), targetColor)
                    }
                }
            }
        }
    }
}

Pro Tip for API 30+

For Android 11 and above, you can replace the systemUiVisibility line with the newer WindowInsetsController API for cleaner code:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    window.insetsController?.setSystemBarsAppearance(
        WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
        WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
    )
}

2. API 16-22 (Android 4.1 Jelly Bean to 5.1 Lollipop)

These versions don't support native status bar icon color changes. You have two reliable options:

Option A: Hide Native Status Bar + Use Custom Layout (Most Compatible)

This is the safest approach across all custom ROMs (MIUI, Samsung One UI, etc.):

  1. Hide the native status bar
  2. Build your own status bar layout with fully customizable icons in #5DD6D6

Code to Hide Native Status Bar

if (Build.VERSION.SDK_INT in Build.VERSION_CODES.JELLY_BEAN..Build.VERSION_CODES.LOLLIPOP_MR1) {
    window.setFlags(
        WindowManager.LayoutParams.FLAG_FULLSCREEN,
        WindowManager.LayoutParams.FLAG_FULLSCREEN
    )
}

Example Custom Status Bar Layout (layout/custom_status_bar.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="25dp"
    android:background="@color/your_status_bar_bg_color"
    android:gravity="end|center_vertical"
    android:paddingHorizontal="16dp">

    <!-- Custom battery icon with target tint -->
    <ImageView
        android:layout_width="20dp"
        android:layout_height="20dp"
        android:src="@drawable/ic_battery"
        android:tint="#5DD6D6"/>

    <!-- Add signal, time, and other icons as needed -->
</LinearLayout>

Option B: Reflection Hack (Less Reliable)

Some ROMs let you access the native status bar view via reflection, but this can break unexpectedly. Use only if you can't implement a custom layout:

fun setStatusBarIconColorPreM(window: Window, targetColor: Int) {
    try {
        val statusBarManager = window.context.getSystemService(Context.STATUS_BAR_SERVICE)
        val field = statusBarManager.javaClass.getDeclaredField("mStatusBarView")
        field.isAccessible = true
        val statusBarView = field.get(statusBarManager) as ViewGroup
        
        for (i in 0 until statusBarView.childCount) {
            statusBarView.getChildAt(i).drawable?.let { drawable ->
                DrawableCompat.setTint(DrawableCompat.wrap(drawable), targetColor)
            }
        }
    } catch (e: Exception) {
        // Catch exceptions for ROMs that block this access
        e.printStackTrace()
    }
}

3. Unified Utility Class

Combine all logic into a single utility class for easy reuse across activities:

object StatusBarIconTintUtils {
    fun applyCustomIconColor(window: Window, targetColor: Int) {
        when {
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> {
                setIconColorForMPlus(window, targetColor)
            }
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN -> {
                // Use custom status bar (recommended)
                hideNativeStatusBar(window)
                // Add your custom_status_bar.xml to your activity layout here
                
                // Uncomment below if you want to try reflection instead
                // setIconColorForPreM(window, targetColor)
            }
            else -> {
                // API <16: No way to modify icon color, stick with default white
            }
        }
    }

    private fun setIconColorForMPlus(window: Window, targetColor: Int) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            window.insetsController?.setSystemBarsAppearance(
                WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
                WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
            )
        } else {
            window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
        }

        val decorView = window.decorView
        val resources = decorView.context.resources
        val iconContainerIds = listOf(
            resources.getIdentifier("statusBarIcons", "id", "android"),
            resources.getIdentifier("statusBarDarkIcons", "id", "android")
        )

        iconContainerIds.forEach { id ->
            decorView.findViewById<ViewGroup>(id)?.let { group ->
                for (i in 0 until group.childCount) {
                    group.getChildAt(i).drawable?.let { drawable ->
                        DrawableCompat.setTint(DrawableCompat.wrap(drawable), targetColor)
                    }
                }
            }
        }
    }

    private fun hideNativeStatusBar(window: Window) {
        window.setFlags(
            WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN
        )
    }

    private fun setIconColorForPreM(window: Window, targetColor: Int) {
        try {
            val statusBarManager = window.context.getSystemService(Context.STATUS_BAR_SERVICE)
            val field = statusBarManager.javaClass.getDeclaredField("mStatusBarView")
            field.isAccessible = true
            val statusBarView = field.get(statusBarManager) as ViewGroup
            
            for (i in 0 until statusBarView.childCount) {
                statusBarView.getChildAt(i).drawable?.let { drawable ->
                    DrawableCompat.setTint(DrawableCompat.wrap(drawable), targetColor)
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}

Key Notes

  • API <16: There's no reliable way to modify status bar icon color—you'll have to stick with the default white.
  • ROM Compatibility: Reflection hacks often fail on custom ROMs, so the custom status bar layout is always the safer bet.
  • Contrast: Make sure your status bar background color contrasts well with #5DD6D6 so icons are visible.

内容的提问来源于stack exchange,提问作者Amin Azizzadeh

火山引擎 最新活动