mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fix status bar height calculation for all cutout sizes (#44697)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/44697 Google has discouraged attempting to read the `status_bar_height` resource [since 2017](https://youtu.be/_mGDMVRO3iE?si=qGQd7gLa_qTmfLGL&t=1079). With the introduction of display cutouts there can be a mismatch between the resource value and the true status bar size (and issues like [this one](https://github.com/facebook/react-native/issues/33612) popped up). The recommended approach is to instead call `getInsets` with the proper status bar and navigation flags provided by `WindowInsets`. On older APIs where `getInsets` is not supported, we have access to `systemWindowInsetTop`. Changelog: [Android][Fixed] - Fixed StatusBar.currentHeight calculations to honor all cutout sizes Reviewed By: cipolleschi, alanleedev Differential Revision: D57878119 fbshipit-source-id: 9fadd33d5f9b617a70a052c98dbd53fd29281650
This commit is contained in:
committed by
Facebook GitHub Bot
parent
db1043dfbf
commit
cc485ccf7d
+27
-18
@@ -12,9 +12,9 @@ import android.animation.ValueAnimator
|
||||
import android.animation.ValueAnimator.AnimatorUpdateListener
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
import android.view.WindowInsets
|
||||
import android.view.WindowInsetsController
|
||||
import android.view.WindowManager
|
||||
import android.view.WindowManager.LayoutParams
|
||||
import androidx.core.view.ViewCompat
|
||||
import com.facebook.common.logging.FLog
|
||||
import com.facebook.fbreact.specs.NativeStatusBarManagerAndroidSpec
|
||||
@@ -33,31 +33,40 @@ public class StatusBarModule(reactContext: ReactApplicationContext?) :
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun getTypedExportedConstants(): Map<String, Any> {
|
||||
val context = getReactApplicationContext()
|
||||
val heightResId = context.resources.getIdentifier("status_bar_height", "dimen", "android")
|
||||
val height =
|
||||
heightResId
|
||||
.takeIf { it > 0 }
|
||||
?.let {
|
||||
PixelUtil.toDIPFromPixel(context.resources.getDimensionPixelSize(it).toFloat())
|
||||
} ?: 0
|
||||
|
||||
var statusBarColorString = "black"
|
||||
val statusBarColor = getCurrentActivity()?.window?.statusBarColor
|
||||
val statusBarColor = currentActivity?.window?.statusBarColor
|
||||
if (statusBarColor != null) {
|
||||
statusBarColorString = String.format("#%06X", 0xFFFFFF and statusBarColor)
|
||||
}
|
||||
|
||||
return mapOf(
|
||||
HEIGHT_KEY to height,
|
||||
HEIGHT_KEY to PixelUtil.toDIPFromPixel(getStatusBarHeightPx()),
|
||||
DEFAULT_BACKGROUND_COLOR_KEY to statusBarColorString,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
private fun getStatusBarHeightPx(): Float {
|
||||
val activity = currentActivity ?: return 0f
|
||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val window = activity.window ?: return 0f
|
||||
val insets =
|
||||
window.decorView.rootWindowInsets.getInsets(
|
||||
WindowInsets.Type.statusBars() or
|
||||
WindowInsets.Type.navigationBars() or
|
||||
WindowInsets.Type.displayCutout())
|
||||
insets.top.toFloat()
|
||||
} else {
|
||||
val window = activity.window ?: return 0f
|
||||
val insets = window.decorView.rootWindowInsets
|
||||
insets.systemWindowInsetTop.toFloat()
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun setColor(colorDouble: Double, animated: Boolean) {
|
||||
val color = colorDouble.toInt()
|
||||
val activity = getCurrentActivity()
|
||||
val activity = currentActivity
|
||||
if (activity == null) {
|
||||
FLog.w(
|
||||
ReactConstants.TAG,
|
||||
@@ -65,7 +74,7 @@ public class StatusBarModule(reactContext: ReactApplicationContext?) :
|
||||
return
|
||||
}
|
||||
UiThreadUtil.runOnUiThread(
|
||||
object : GuardedRunnable(getReactApplicationContext()) {
|
||||
object : GuardedRunnable(reactApplicationContext) {
|
||||
override fun runGuarded() {
|
||||
val window = activity.window ?: return
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
|
||||
@@ -89,7 +98,7 @@ public class StatusBarModule(reactContext: ReactApplicationContext?) :
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun setTranslucent(translucent: Boolean) {
|
||||
val activity = getCurrentActivity()
|
||||
val activity = currentActivity
|
||||
if (activity == null) {
|
||||
FLog.w(
|
||||
ReactConstants.TAG,
|
||||
@@ -97,7 +106,7 @@ public class StatusBarModule(reactContext: ReactApplicationContext?) :
|
||||
return
|
||||
}
|
||||
UiThreadUtil.runOnUiThread(
|
||||
object : GuardedRunnable(getReactApplicationContext()) {
|
||||
object : GuardedRunnable(reactApplicationContext) {
|
||||
override fun runGuarded() {
|
||||
// If the status bar is translucent hook into the window insets calculations
|
||||
// and consume all the top insets so no padding will be added under the status bar.
|
||||
@@ -122,7 +131,7 @@ public class StatusBarModule(reactContext: ReactApplicationContext?) :
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun setHidden(hidden: Boolean) {
|
||||
val activity = getCurrentActivity()
|
||||
val activity = currentActivity
|
||||
if (activity == null) {
|
||||
FLog.w(
|
||||
ReactConstants.TAG,
|
||||
@@ -144,7 +153,7 @@ public class StatusBarModule(reactContext: ReactApplicationContext?) :
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun setStyle(style: String?) {
|
||||
val activity = getCurrentActivity()
|
||||
val activity = currentActivity
|
||||
if (activity == null) {
|
||||
FLog.w(
|
||||
ReactConstants.TAG,
|
||||
|
||||
Reference in New Issue
Block a user