-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Expand file tree
/
Copy pathSystemUiUtils.kt
More file actions
168 lines (148 loc) · 5.52 KB
/
SystemUiUtils.kt
File metadata and controls
168 lines (148 loc) · 5.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package com.reactnativenavigation.utils
import android.app.Activity
import android.graphics.Color
import android.graphics.Rect
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
internal 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)
}
} ?: STATUS_BAR_HEIGHT_M
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) {
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 colorAlpha = Color.alpha(color)
val alpha = if (translucent && colorAlpha == 255) STATUS_BAR_HEIGHT_TRANSLUCENCY else colorAlpha/255.0f
val red: Int = Color.red(color)
val green: Int = Color.green(color)
val blue: Int = Color.blue(color)
val opaqueColor = Color.argb(ceil(alpha * 255).toInt(), red, green, blue)
setStatusBarColor(window, opaqueColor)
}
fun setStatusBarColor(window: Window?, color: Int) {
window?.statusBarColor = color
}
@JvmStatic
fun getStatusBarColor(window: Window?): Int? {
return window?.statusBarColor
}
@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
}
}
}