79314721

Date: 2024-12-28 23:32:12
Score: 0.5
Natty:
Report link

In my case, my activity content was complex, so accessing it through Custom-Theme method was not suitable. @Shouheng Wang's suggestion was the best, but his suggestion needs some modifications. First, I changed it to Kotlin code. And 'resources.getIdentifier' is slow/heavy and is not recommended. My suggestions for improvement are as follows:

Step 1.

Create a 'BarUtils.kt' file. And fill in the following code:

object BarUtils {
   private const val TAG_STATUS_BAR = "TAG_STATUS_BAR"

   // for Lollipop (SDK 21+)
   fun transparentStatusBar(window: Window) {
       window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
       window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
       val option =
       View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
       val vis = window.decorView.systemUiVisibility
       window.decorView.systemUiVisibility = option or vis
       window.statusBarColor = Color.TRANSPARENT
   }

   fun applyStatusBarColor (window: Window, color: Int, isDecor: Boolean, getStatusBarHeight: Int): View {
       val parent = if (isDecor) window.decorView as ViewGroup else (window.findViewById<View>(R.id.content) as ViewGroup)
       var fakeStatusBarView = parent.findViewWithTag<View>(TAG_STATUS_BAR)
       if (fakeStatusBarView != null) {
           if (fakeStatusBarView.visibility == View.GONE) {
              fakeStatusBarView.visibility = View.VISIBLE
           }
          fakeStatusBarView.setBackgroundColor(color)
       } else {
          fakeStatusBarView = **createStatusBarView** (window, color, getStatusBarHeight)
          parent.addView(fakeStatusBarView)
       }
       return fakeStatusBarView
   }

   private fun createStatusBarView (window: Window, color: Int, **getStatusBarHeight**: Int): View {
       val statusBarView = View(window.context)
       statusBarView.layoutParams = ViewGroup.LayoutParams(
          ViewGroup.LayoutParams.MATCH_PARENT, **getStatusBarHeight**
       )
       statusBarView.setBackgroundColor(color)
       statusBarView.tag = TAG_STATUS_BAR
       return statusBarView
   }

}

Step 2:

Then, insert the following code into the Activity to get getStatusBarHeight, which is the height of the Status Bar.

if (Build.VERSION.SDK_INT >= 24) {
   enableEdgeToEdge()
   ViewCompat.setOnApplyWindowInsetsListener(maBinding.root) { v, windowInsets ->
      val currentNightMode = (resources.configuration.uiMode
                 and Configuration.UI_MODE_NIGHT_MASK)
      val insets = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars())
      v.run {
          updateLayoutParams<ViewGroup.MarginLayoutParams> {
             topMargin = insets.top
             when (currentNightMode) {
                  Configuration.UI_MODE_NIGHT_NO -> {
                     BarUtils.applyStatusBarColor(window, Color.WHITE,true, topMargin)
                  }
                  Configuration.UI_MODE_NIGHT_YES -> {
                     BarUtils.applyStatusBarColor(window, Color.BLACK,true, topMargin)
                  }
                  Configuration.UI_MODE_NIGHT_UNDEFINED -> {
                     BarUtils.applyStatusBarColor(window, Color.WHITE,true, topMargin)
                  }
              }
          }
      }
      windowInsets
      //WindowInsetsCompat.CONSUMED
  }      
}  else {
    BarUtils.transparentStatusBar(window)
}

note:

  1. If you forget enableEdgeToEdge(), the StatusBar color will not appear correctly.

  2. A crash occurs if it is located before the activity's setContentView().

  3. If you do not use v.run {}, 'ViewCompat' changes the height of the activity StatusBar. Don't forget that this code only retrieves the value of 'getStatusBarHeight'. (For the same reason, 'windowInsets' was used instead of 'WindowInsetsCompat.CONSUMED'.)

  4. The 'currentNightMode' part is for dark mode.

Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @Shouheng
  • Low reputation (1):
Posted by: Young Lee