-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Upgrading android target SDK to 30, to support android 12 changes. - Refactor StatusBarUtil to SystemUIUtils to include status and navigation bars. - Migrate deprecated code using flags to a modern one. - Calculating WindowInsets per component where all views are laid as full screen. - Keyboard enhancements to show hide keyboard. - Fix applying Options of a child taking parent Options into consideration. - Fix fixed status bar height and use a more elegant way. - Add more tests for SystemUiUtils. - Add a SystemUi screen to demonstrate system UI capabilities. - Migrate Reanimated usage to support Reanimated 2. Closes #7339. Closes #7225. Closes #7358. Closes #7199. Closes #7171. Closes #7111. Closes #6988. Closes #4258. Closes #7360. Demo: https://user-images.githubusercontent.com/7227793/142203865-d65b6910-21f8-4617-812e-b5576a6b58e4.mov Co-authored-by: Ward Abbass <[email protected]> Co-authored-by: Yogev Ben David <[email protected]> Co-authored-by: svbutko <[email protected]> Co-authored-by: Ward Abbass <[email protected]>
- Loading branch information
1 parent
29ac5e4
commit eae5831
Showing
37 changed files
with
662 additions
and
302 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 0 additions & 39 deletions
39
lib/android/app/src/main/java/com/reactnativenavigation/utils/StatusBarUtils.kt
This file was deleted.
Oops, something went wrong.
168 changes: 168 additions & 0 deletions
168
lib/android/app/src/main/java/com/reactnativenavigation/utils/SystemUiUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
package com.reactnativenavigation.utils | ||
|
||
import android.app.Activity | ||
import android.graphics.Color | ||
import android.graphics.Rect | ||
import android.os.Build | ||
import android.view.View | ||
import android.view.Window | ||
import androidx.annotation.ColorInt | ||
import androidx.core.view.WindowCompat | ||
import androidx.core.view.WindowInsetsCompat | ||
import androidx.core.view.WindowInsetsControllerCompat | ||
import kotlin.math.abs | ||
import kotlin.math.ceil | ||
|
||
|
||
object SystemUiUtils { | ||
private const val STATUS_BAR_HEIGHT_M = 24 | ||
private const val STATUS_BAR_HEIGHT_L = 25 | ||
private const val STATUS_BAR_HEIGHT_TRANSLUCENCY = 0.65f | ||
private var statusBarHeight = -1 | ||
var navigationBarDefaultColor = -1 | ||
private set | ||
|
||
|
||
@JvmStatic | ||
fun getStatusBarHeight(activity: Activity?): Int { | ||
val res = if (statusBarHeight > 0) { | ||
statusBarHeight | ||
} else { | ||
statusBarHeight = activity?.let { | ||
val rectangle = Rect() | ||
val window: Window = activity.window | ||
window.decorView.getWindowVisibleDisplayFrame(rectangle) | ||
val statusBarHeight: Int = rectangle.top | ||
val contentView = window.findViewById<View>(Window.ID_ANDROID_CONTENT) | ||
contentView?.let { | ||
val contentViewTop = contentView.top | ||
abs(contentViewTop - statusBarHeight) | ||
} | ||
} ?: if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) STATUS_BAR_HEIGHT_M else STATUS_BAR_HEIGHT_L | ||
statusBarHeight | ||
} | ||
return res | ||
} | ||
|
||
@JvmStatic | ||
fun saveStatusBarHeight(height: Int) { | ||
statusBarHeight = height | ||
} | ||
|
||
|
||
@JvmStatic | ||
fun getStatusBarHeightDp(activity: Activity?): Int { | ||
return UiUtils.pxToDp(activity, getStatusBarHeight(activity).toFloat()) | ||
.toInt() | ||
} | ||
|
||
@JvmStatic | ||
fun hideNavigationBar(window: Window?, view: View) { | ||
window?.let { | ||
WindowCompat.setDecorFitsSystemWindows(window, false) | ||
WindowInsetsControllerCompat(window, view).let { controller -> | ||
controller.hide(WindowInsetsCompat.Type.navigationBars()) | ||
controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE | ||
} | ||
} | ||
} | ||
|
||
@JvmStatic | ||
fun showNavigationBar(window: Window?, view: View) { | ||
window?.let { | ||
WindowCompat.setDecorFitsSystemWindows(window, true) | ||
WindowInsetsControllerCompat(window, view).show(WindowInsetsCompat.Type.navigationBars()) | ||
} | ||
} | ||
|
||
@JvmStatic | ||
fun setStatusBarColorScheme(window: Window?, view: View, isDark: Boolean) { | ||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return | ||
|
||
window?.let { | ||
WindowInsetsControllerCompat(window, view).isAppearanceLightStatusBars = isDark | ||
// Workaround: on devices with api 30 status bar icons flickers or get hidden when removing view | ||
//turns out it is a bug on such devices, fixed by using system flags until it is fixed. | ||
var flags = view.systemUiVisibility | ||
flags = if (isDark) { | ||
flags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | ||
} else { | ||
flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv() | ||
} | ||
|
||
view.systemUiVisibility = flags | ||
} | ||
} | ||
|
||
@JvmStatic | ||
fun setStatusBarTranslucent(window: Window?) { | ||
window?.let { | ||
setStatusBarColor(window, window.statusBarColor, true) | ||
} | ||
} | ||
|
||
@JvmStatic | ||
fun isTranslucent(window: Window?): Boolean { | ||
return window?.let { | ||
Color.alpha(it.statusBarColor) < 255 | ||
} ?: false | ||
} | ||
|
||
@JvmStatic | ||
fun clearStatusBarTranslucency(window: Window?) { | ||
window?.let { | ||
setStatusBarColor(it, it.statusBarColor, false) | ||
} | ||
} | ||
|
||
@JvmStatic | ||
fun setStatusBarColor( | ||
window: Window?, | ||
@ColorInt color: Int, | ||
translucent: Boolean | ||
) { | ||
val opaqueColor = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { | ||
Color.BLACK | ||
}else{ | ||
val alpha = if (translucent) STATUS_BAR_HEIGHT_TRANSLUCENCY else 1f | ||
val red: Int = Color.red(color) | ||
val green: Int = Color.green(color) | ||
val blue: Int = Color.blue(color) | ||
Color.argb(ceil(alpha * 255).toInt(), red, green, blue) | ||
} | ||
window?.statusBarColor = opaqueColor | ||
} | ||
|
||
@JvmStatic | ||
fun hideStatusBar(window: Window?, view: View) { | ||
window?.let { | ||
WindowCompat.setDecorFitsSystemWindows(window, false) | ||
WindowInsetsControllerCompat(window, view).let { controller -> | ||
controller.hide(WindowInsetsCompat.Type.statusBars()) | ||
controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE | ||
} | ||
} | ||
} | ||
|
||
@JvmStatic | ||
fun showStatusBar(window: Window?, view: View) { | ||
window?.let { | ||
WindowCompat.setDecorFitsSystemWindows(window, true) | ||
WindowInsetsControllerCompat(window, view).show(WindowInsetsCompat.Type.statusBars()) | ||
} | ||
} | ||
|
||
@JvmStatic | ||
fun setNavigationBarBackgroundColor(window: Window?, color: Int, lightColor: Boolean) { | ||
window?.let { | ||
if (navigationBarDefaultColor == -1) { | ||
navigationBarDefaultColor = window.navigationBarColor | ||
} | ||
WindowInsetsControllerCompat(window, window.decorView).let { controller -> | ||
controller.isAppearanceLightNavigationBars = lightColor | ||
} | ||
window.navigationBarColor = color | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.