如何在Android全版本中修改状态栏图标颜色?
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.):
- Hide the native status bar
- 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
#5DD6D6so icons are visible.
内容的提问来源于stack exchange,提问作者Amin Azizzadeh




