react-native-navigation 7.42.0 → 7.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/android/app/src/main/java/com/reactnativenavigation/FeatureToggles.kt +62 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java +2 -2
- package/lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java +13 -3
- package/lib/android/app/src/main/java/com/reactnativenavigation/options/ValueAnimationOptions.kt +3 -3
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ColorUtils.java +11 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/StubAnimationListener.kt +19 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/SystemUiUtils.kt +17 -16
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabPresenter.java +0 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsAnimator.kt +2 -2
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsController.java +4 -9
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java +7 -14
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/component/ComponentPresenter.java +18 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/component/ComponentViewController.java +24 -12
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackController.java +52 -24
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackPresenter.java +20 -10
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/{TopBarAnimator.kt → TopBarAppearanceAnimator.kt} +4 -2
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/TopBarCollapseBehavior.kt +1 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/TopBarController.kt +154 -26
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/statusbar/StatusBarPresenter.kt +212 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/Presenter.java +12 -107
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/StatusBarColorAnimator.kt +28 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/ViewController.java +34 -2
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/ViewControllerVisibilityInfo.kt +5 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/{BaseViewAnimator.kt → BaseViewAppearanceAnimator.kt} +4 -4
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/ColorAnimator.kt +22 -0
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/DefaultViewAnimatorCreator.kt +8 -8
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/ViewAnimatorCreator.kt +2 -2
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/ViewBkgColorProperty.kt +17 -0
- package/lib/dist/src/commands/OptionsProcessor.js +8 -1
- package/lib/dist/src/interfaces/Options.d.ts +33 -3
- package/lib/ios/BottomTabsBasePresenter.m +1 -1
- package/lib/ios/RNNConvert.h +0 -1
- package/lib/ios/RNNConvert.m +3 -8
- package/lib/ios/RNNStackPresenter.m +1 -1
- package/lib/src/commands/OptionsProcessor.ts +13 -2
- package/lib/src/interfaces/Options.ts +38 -3
- package/package.json +1 -1
|
@@ -1,28 +1,44 @@
|
|
|
1
1
|
package com.reactnativenavigation.viewcontrollers.stack.topbar
|
|
2
2
|
|
|
3
3
|
import android.animation.Animator
|
|
4
|
+
import android.animation.AnimatorSet
|
|
4
5
|
import android.content.Context
|
|
6
|
+
import android.graphics.drawable.ColorDrawable
|
|
7
|
+
import android.os.Build
|
|
5
8
|
import android.view.MenuItem
|
|
6
9
|
import android.view.View
|
|
10
|
+
import androidx.core.animation.addListener
|
|
11
|
+
import androidx.core.animation.doOnEnd
|
|
7
12
|
import androidx.viewpager.widget.ViewPager
|
|
13
|
+
import com.reactnativenavigation.RNNFeatureToggles
|
|
14
|
+
import com.reactnativenavigation.RNNToggles
|
|
8
15
|
import com.reactnativenavigation.options.Alignment
|
|
9
16
|
import com.reactnativenavigation.options.AnimationOptions
|
|
10
17
|
import com.reactnativenavigation.options.Options
|
|
18
|
+
import com.reactnativenavigation.options.TopBarOptions
|
|
19
|
+
import com.reactnativenavigation.options.animations.ViewAnimationOptions
|
|
11
20
|
import com.reactnativenavigation.utils.CollectionUtils.forEachIndexed
|
|
12
21
|
import com.reactnativenavigation.utils.ViewUtils
|
|
13
22
|
import com.reactnativenavigation.utils.resetViewProperties
|
|
14
23
|
import com.reactnativenavigation.viewcontrollers.stack.topbar.button.ButtonController
|
|
15
24
|
import com.reactnativenavigation.viewcontrollers.stack.topbar.title.TitleBarReactViewController
|
|
25
|
+
import com.reactnativenavigation.viewcontrollers.viewcontroller.TopBarVisibilityInfo
|
|
26
|
+
import com.reactnativenavigation.viewcontrollers.viewcontroller.ViewController
|
|
27
|
+
import com.reactnativenavigation.views.animations.ColorAnimator
|
|
16
28
|
import com.reactnativenavigation.views.stack.StackLayout
|
|
17
29
|
import com.reactnativenavigation.views.stack.topbar.TopBar
|
|
18
30
|
import com.reactnativenavigation.views.stack.topbar.titlebar.ButtonBar
|
|
19
31
|
|
|
20
32
|
|
|
21
|
-
open class TopBarController(
|
|
33
|
+
open class TopBarController(
|
|
34
|
+
private val appearAnimator: TopBarAppearanceAnimator = TopBarAppearanceAnimator(),
|
|
35
|
+
private val colorAnimator: ColorAnimator = ColorAnimator(),
|
|
36
|
+
) {
|
|
22
37
|
lateinit var view: TopBar
|
|
23
38
|
private lateinit var leftButtonBar: ButtonBar
|
|
24
39
|
private lateinit var rightButtonBar: ButtonBar
|
|
25
40
|
|
|
41
|
+
private var hasPendingColorAnim = false
|
|
26
42
|
|
|
27
43
|
val height: Int
|
|
28
44
|
get() = view.height
|
|
@@ -31,70 +47,142 @@ open class TopBarController(private val animator: TopBarAnimator = TopBarAnimato
|
|
|
31
47
|
val leftButtonCount: Int
|
|
32
48
|
get() = leftButtonBar.buttonCount
|
|
33
49
|
|
|
34
|
-
|
|
50
|
+
val visibilityInfo: TopBarVisibilityInfo
|
|
51
|
+
get() = TopBarVisibilityInfo(view.isShown, getBackgroundColor())
|
|
35
52
|
|
|
36
53
|
fun createView(context: Context, parent: StackLayout): TopBar {
|
|
37
54
|
if (!::view.isInitialized) {
|
|
38
55
|
view = createTopBar(context, parent)
|
|
39
56
|
leftButtonBar = view.leftButtonBar
|
|
40
57
|
rightButtonBar = view.rightButtonBar
|
|
41
|
-
|
|
58
|
+
appearAnimator.bindView(view)
|
|
42
59
|
}
|
|
43
60
|
return view
|
|
44
61
|
}
|
|
45
62
|
|
|
46
|
-
protected open fun createTopBar(context: Context, stackLayout: StackLayout): TopBar {
|
|
47
|
-
return TopBar(context)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
63
|
fun initTopTabs(viewPager: ViewPager?) = view.initTopTabs(viewPager)
|
|
51
64
|
|
|
52
65
|
fun clearTopTabs() = view.clearTopTabs()
|
|
53
66
|
|
|
67
|
+
fun setBackgroundColor(topBarOptions: TopBarOptions, defaultColor: Int) {
|
|
68
|
+
val color = topBarOptions.background.color
|
|
69
|
+
|
|
70
|
+
if (!hasPendingColorAnim) {
|
|
71
|
+
view.setBackgroundColor(color.get(defaultColor)!!)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
fun setBackgroundColor(topBarOptions: TopBarOptions) {
|
|
76
|
+
val color = topBarOptions.background.color
|
|
77
|
+
|
|
78
|
+
if (color.hasValue() && !hasPendingColorAnim) {
|
|
79
|
+
view.setBackgroundColor(color.get())
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
fun getBackgroundColor(): Int? {
|
|
84
|
+
return if (view.background is ColorDrawable) {
|
|
85
|
+
(view.background as ColorDrawable).color
|
|
86
|
+
} else {
|
|
87
|
+
null
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
fun getRightButton(index: Int): MenuItem = rightButtonBar.getButton(index)
|
|
92
|
+
|
|
54
93
|
fun getPushAnimation(appearingOptions: Options, additionalDy: Float = 0f): Animator? {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
94
|
+
val topBarOptions = appearingOptions.topBar
|
|
95
|
+
val topBarAnimOptions = appearingOptions.animations.push.topBar
|
|
96
|
+
|
|
97
|
+
hasPendingColorAnim = false
|
|
98
|
+
|
|
99
|
+
mutableListOf(
|
|
100
|
+
getAppearancePushAnimation(topBarOptions, topBarAnimOptions, additionalDy),
|
|
101
|
+
getBkgColorAnimation(topBarOptions)?.apply {
|
|
102
|
+
hasPendingColorAnim = true
|
|
103
|
+
|
|
104
|
+
addListener(onEnd = {
|
|
105
|
+
hasPendingColorAnim = false
|
|
106
|
+
})
|
|
107
|
+
},
|
|
108
|
+
).filterNotNull().let {
|
|
109
|
+
return if (it.isNotEmpty()) {
|
|
110
|
+
AnimatorSet().apply { playTogether(it) }
|
|
111
|
+
} else {
|
|
112
|
+
null
|
|
113
|
+
}
|
|
114
|
+
}
|
|
61
115
|
}
|
|
62
116
|
|
|
63
117
|
fun getPopAnimation(appearingOptions: Options, disappearingOptions: Options): Animator? {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
118
|
+
val topBarOptions = appearingOptions.topBar
|
|
119
|
+
val topBarAnimOptions = disappearingOptions.animations.pop.topBar
|
|
120
|
+
|
|
121
|
+
hasPendingColorAnim = false
|
|
122
|
+
|
|
123
|
+
mutableListOf(
|
|
124
|
+
getAppearancePopAnimation(topBarOptions, topBarAnimOptions),
|
|
125
|
+
getBkgColorAnimation(topBarOptions)?.apply {
|
|
126
|
+
hasPendingColorAnim = true
|
|
127
|
+
|
|
128
|
+
addListener(onEnd = {
|
|
129
|
+
hasPendingColorAnim = false
|
|
130
|
+
})
|
|
131
|
+
},
|
|
132
|
+
).filterNotNull().let {
|
|
133
|
+
return if (it.isNotEmpty()) {
|
|
134
|
+
AnimatorSet().apply { playTogether(it) }
|
|
135
|
+
} else {
|
|
136
|
+
null
|
|
137
|
+
}
|
|
138
|
+
}
|
|
69
139
|
}
|
|
70
140
|
|
|
71
141
|
fun getSetStackRootAnimation(appearingOptions: Options, additionalDy: Float = 0f): Animator? {
|
|
72
142
|
if (appearingOptions.topBar.animate.isFalse) return null
|
|
73
|
-
return
|
|
143
|
+
return appearAnimator.getSetStackRootAnimation(
|
|
74
144
|
appearingOptions.animations.setStackRoot.topBar,
|
|
75
145
|
appearingOptions.topBar.visible,
|
|
76
146
|
additionalDy
|
|
77
147
|
)
|
|
78
148
|
}
|
|
79
149
|
|
|
150
|
+
fun bindNewViewController(previousVC: ViewController<*>?, newVC: ViewController<*>?) {
|
|
151
|
+
if (!RNNFeatureToggles.isEnabled(RNNToggles.TOP_BAR_COLOR_ANIMATION__TABS)) {
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
previousVC?.visibilityInfo?.topBarVisibilityInfo?.solidColor?.let { fromColor ->
|
|
156
|
+
newVC?.visibilityInfo?.topBarVisibilityInfo?.solidColor?.let { toColor ->
|
|
157
|
+
colorAnimator.getAnimation(view, fromColor, toColor).apply {
|
|
158
|
+
doOnEnd {
|
|
159
|
+
hasPendingColorAnim = false
|
|
160
|
+
}
|
|
161
|
+
hasPendingColorAnim = true
|
|
162
|
+
start()
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
80
168
|
fun show() {
|
|
81
|
-
if (ViewUtils.isVisible(view) ||
|
|
169
|
+
if (ViewUtils.isVisible(view) || appearAnimator.isAnimatingShow()) return
|
|
82
170
|
view.resetViewProperties()
|
|
83
171
|
view.visibility = View.VISIBLE
|
|
84
172
|
}
|
|
85
173
|
|
|
86
174
|
fun showAnimate(options: AnimationOptions, additionalDy: Float) {
|
|
87
|
-
if (ViewUtils.isVisible(view) ||
|
|
88
|
-
|
|
175
|
+
if (ViewUtils.isVisible(view) || appearAnimator.isAnimatingShow()) return
|
|
176
|
+
appearAnimator.show(options, additionalDy)
|
|
89
177
|
}
|
|
90
178
|
|
|
91
179
|
fun hide() {
|
|
92
|
-
if (!
|
|
180
|
+
if (!appearAnimator.isAnimatingHide()) view.visibility = View.GONE
|
|
93
181
|
}
|
|
94
182
|
|
|
95
183
|
fun hideAnimate(options: AnimationOptions, additionalDy: Float) {
|
|
96
|
-
if (!ViewUtils.isVisible(view) ||
|
|
97
|
-
|
|
184
|
+
if (!ViewUtils.isVisible(view) || appearAnimator.isAnimatingHide()) return
|
|
185
|
+
appearAnimator.hide(options, additionalDy)
|
|
98
186
|
}
|
|
99
187
|
|
|
100
188
|
fun setTitleComponent(component: TitleBarReactViewController) {
|
|
@@ -126,4 +214,44 @@ open class TopBarController(private val animator: TopBarAnimator = TopBarAnimato
|
|
|
126
214
|
toRemove.forEach { view.removeLeftButton(it) }
|
|
127
215
|
forEachIndexed(toAdd) { b: ButtonController, i: Int -> b.addToMenu(leftButtonBar, i * 10) }
|
|
128
216
|
}
|
|
129
|
-
|
|
217
|
+
|
|
218
|
+
protected open fun createTopBar(context: Context, stackLayout: StackLayout): TopBar {
|
|
219
|
+
return TopBar(context)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private fun getBkgColorAnimation(topBarOptions: TopBarOptions): Animator? {
|
|
223
|
+
val targetColor = topBarOptions.background.color
|
|
224
|
+
|
|
225
|
+
if (targetColor.hasValue()
|
|
226
|
+
&& view.background is ColorDrawable
|
|
227
|
+
&& RNNFeatureToggles.isEnabled(RNNToggles.TOP_BAR_COLOR_ANIMATION__PUSH)) {
|
|
228
|
+
return colorAnimator.getAnimation(
|
|
229
|
+
view,
|
|
230
|
+
(view.background as ColorDrawable).color,
|
|
231
|
+
targetColor.get()
|
|
232
|
+
)
|
|
233
|
+
}
|
|
234
|
+
return null
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
private fun getAppearancePushAnimation(topBarOptions: TopBarOptions, topBarAnimOptions: ViewAnimationOptions, additionalDy: Float) =
|
|
238
|
+
if (!topBarOptions.animate.isFalse) {
|
|
239
|
+
appearAnimator.getPushAnimation(
|
|
240
|
+
topBarAnimOptions,
|
|
241
|
+
topBarOptions.visible,
|
|
242
|
+
additionalDy,
|
|
243
|
+
)
|
|
244
|
+
} else {
|
|
245
|
+
null
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
private fun getAppearancePopAnimation(topBarOptions: TopBarOptions, topBarAnimOptions: ViewAnimationOptions) =
|
|
249
|
+
if (!topBarOptions.animate.isFalse) {
|
|
250
|
+
appearAnimator.getPopAnimation(
|
|
251
|
+
topBarAnimOptions,
|
|
252
|
+
topBarOptions.visible,
|
|
253
|
+
)
|
|
254
|
+
} else {
|
|
255
|
+
null
|
|
256
|
+
}
|
|
257
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
package com.reactnativenavigation.viewcontrollers.statusbar
|
|
2
|
+
|
|
3
|
+
import android.animation.Animator
|
|
4
|
+
import android.app.Activity
|
|
5
|
+
import android.graphics.Color
|
|
6
|
+
import android.view.View
|
|
7
|
+
import android.view.Window
|
|
8
|
+
import com.reactnativenavigation.RNNFeatureToggles.isEnabled
|
|
9
|
+
import com.reactnativenavigation.RNNToggles
|
|
10
|
+
import com.reactnativenavigation.options.Options
|
|
11
|
+
import com.reactnativenavigation.options.StatusBarOptions
|
|
12
|
+
import com.reactnativenavigation.options.StatusBarOptions.TextColorScheme
|
|
13
|
+
import com.reactnativenavigation.options.params.Bool
|
|
14
|
+
import com.reactnativenavigation.utils.ColorUtils.isColorLight
|
|
15
|
+
import com.reactnativenavigation.utils.StubAnimationListener.Companion.onAnimatorEnd
|
|
16
|
+
import com.reactnativenavigation.utils.SystemUiUtils.clearStatusBarTranslucency
|
|
17
|
+
import com.reactnativenavigation.utils.SystemUiUtils.getStatusBarColor
|
|
18
|
+
import com.reactnativenavigation.utils.SystemUiUtils.hideStatusBar
|
|
19
|
+
import com.reactnativenavigation.utils.SystemUiUtils.isTranslucent
|
|
20
|
+
import com.reactnativenavigation.utils.SystemUiUtils.setStatusBarColor
|
|
21
|
+
import com.reactnativenavigation.utils.SystemUiUtils.setStatusBarColorScheme
|
|
22
|
+
import com.reactnativenavigation.utils.SystemUiUtils.setStatusBarTranslucent
|
|
23
|
+
import com.reactnativenavigation.utils.SystemUiUtils.showStatusBar
|
|
24
|
+
import com.reactnativenavigation.viewcontrollers.viewcontroller.StatusBarColorAnimator
|
|
25
|
+
import com.reactnativenavigation.viewcontrollers.viewcontroller.ViewController
|
|
26
|
+
import java.lang.ref.WeakReference
|
|
27
|
+
|
|
28
|
+
class StatusBarPresenter private constructor(
|
|
29
|
+
activity: Activity,
|
|
30
|
+
private val sbColorAnimator: StatusBarColorAnimator = StatusBarColorAnimator(activity)) {
|
|
31
|
+
|
|
32
|
+
private val window = WeakReference(activity.window)
|
|
33
|
+
private var hasPendingColorAnim = false
|
|
34
|
+
|
|
35
|
+
fun applyOptions(viewController: ViewController<*>, options: StatusBarOptions) {
|
|
36
|
+
if (!hasPendingColorAnim) {
|
|
37
|
+
setStatusBarBackgroundColor(options)
|
|
38
|
+
setTranslucent(options)
|
|
39
|
+
}
|
|
40
|
+
setTextColorScheme(options)
|
|
41
|
+
setStatusBarVisible(viewController, options.visible)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fun mergeOptions(view: View, statusBar: StatusBarOptions) {
|
|
45
|
+
mergeStatusBarBackgroundColor(statusBar)
|
|
46
|
+
mergeTextColorScheme(statusBar)
|
|
47
|
+
mergeTranslucent(statusBar)
|
|
48
|
+
mergeStatusBarVisible(view, statusBar.visible)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
fun onConfigurationChanged(options: StatusBarOptions) {
|
|
52
|
+
setStatusBarBackgroundColor(options)
|
|
53
|
+
setTextColorScheme(options)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
fun bindViewController(newOptions: StatusBarOptions) {
|
|
57
|
+
if (!isEnabled(RNNToggles.TOP_BAR_COLOR_ANIMATION__TABS)) {
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (newOptions.backgroundColor.canApplyValue()) {
|
|
62
|
+
val currentColor = getCurrentStatusBarBackgroundColor() ?: return
|
|
63
|
+
val newColor = getStatusBarBackgroundColor(newOptions)
|
|
64
|
+
createStatusBarColorAnimation(
|
|
65
|
+
from = currentColor,
|
|
66
|
+
to = newColor,
|
|
67
|
+
translucent = newOptions.translucent.isTrue,
|
|
68
|
+
).start()
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
fun getStatusBarPushAnimation(appearingOptions: Options): Animator? =
|
|
73
|
+
if (isEnabled(RNNToggles.TOP_BAR_COLOR_ANIMATION__PUSH)) {
|
|
74
|
+
getStatusBarColorAnimation(appearingOptions.statusBar)
|
|
75
|
+
} else null
|
|
76
|
+
|
|
77
|
+
fun getStatusBarPopAnimation(appearingOptions: Options, disappearingOptions: Options): Animator? =
|
|
78
|
+
if (isEnabled(RNNToggles.TOP_BAR_COLOR_ANIMATION__PUSH)) {
|
|
79
|
+
getStatusBarColorAnimation(appearingOptions.statusBar)
|
|
80
|
+
} else null
|
|
81
|
+
|
|
82
|
+
private fun setStatusBarBackgroundColor(statusBar: StatusBarOptions) {
|
|
83
|
+
if (statusBar.backgroundColor.canApplyValue()) {
|
|
84
|
+
val statusBarBackgroundColor: Int = getStatusBarBackgroundColor(statusBar)
|
|
85
|
+
setStatusBarBackgroundColor(statusBarBackgroundColor, statusBar.translucent.isTrue)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private fun setStatusBarBackgroundColor(color: Int, translucent: Boolean) {
|
|
90
|
+
setStatusBarColor(window.get(), color, translucent)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
private fun getStatusBarBackgroundColor(statusBar: StatusBarOptions): Int {
|
|
94
|
+
val defaultColor =
|
|
95
|
+
if (statusBar.visible.isTrueOrUndefined) Color.BLACK else Color.TRANSPARENT
|
|
96
|
+
return statusBar.backgroundColor.get(defaultColor)!!
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private fun setTextColorScheme(statusBar: StatusBarOptions) {
|
|
100
|
+
val view = window.get()?.decorView
|
|
101
|
+
//View.post is a Workaround, added to solve internal Samsung
|
|
102
|
+
//Android 9 issues. For more info see https://github.com/wix/react-native-navigation/pull/7231
|
|
103
|
+
view?.post {
|
|
104
|
+
setStatusBarColorScheme(
|
|
105
|
+
window.get(),
|
|
106
|
+
view,
|
|
107
|
+
isDarkTextColorScheme(statusBar)
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private fun setTranslucent(options: StatusBarOptions) {
|
|
113
|
+
val window = window.get()
|
|
114
|
+
if (options.translucent.isTrue) {
|
|
115
|
+
setStatusBarTranslucent(window)
|
|
116
|
+
} else if (isTranslucent(window)) {
|
|
117
|
+
clearStatusBarTranslucency(window)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private fun setStatusBarVisible(viewController: ViewController<*>, visible: Bool) {
|
|
122
|
+
val window = window.get() ?: return
|
|
123
|
+
val view = if (viewController.view != null) viewController.view else window.decorView
|
|
124
|
+
if (visible.isFalse) {
|
|
125
|
+
hideStatusBar(window, view)
|
|
126
|
+
} else {
|
|
127
|
+
showStatusBar(window, view)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private fun mergeStatusBarBackgroundColor(statusBar: StatusBarOptions) {
|
|
132
|
+
if (statusBar.backgroundColor.hasValue()) {
|
|
133
|
+
val statusBarBackgroundColor = getStatusBarBackgroundColor(statusBar)
|
|
134
|
+
setStatusBarColor(
|
|
135
|
+
window.get(), statusBarBackgroundColor,
|
|
136
|
+
statusBar.translucent.isTrue
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private fun mergeTextColorScheme(statusBar: StatusBarOptions) {
|
|
142
|
+
if (!statusBar.textColorScheme.hasValue()) return
|
|
143
|
+
setTextColorScheme(statusBar)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private fun mergeTranslucent(options: StatusBarOptions) {
|
|
147
|
+
val window: Window = window.get() ?: return
|
|
148
|
+
if (options.translucent.isTrue) {
|
|
149
|
+
setStatusBarTranslucent(window)
|
|
150
|
+
} else if (options.translucent.isFalse && isTranslucent(window)) {
|
|
151
|
+
clearStatusBarTranslucency(window)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private fun mergeStatusBarVisible(view: View, visible: Bool) {
|
|
156
|
+
if (visible.hasValue()) {
|
|
157
|
+
if (visible.isTrue) {
|
|
158
|
+
showStatusBar(window.get(), view)
|
|
159
|
+
} else {
|
|
160
|
+
hideStatusBar(window.get(), view)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private fun isDarkTextColorScheme(statusBar: StatusBarOptions): Boolean {
|
|
166
|
+
if (statusBar.textColorScheme == TextColorScheme.Dark) {
|
|
167
|
+
return true
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (statusBar.textColorScheme == TextColorScheme.Light) {
|
|
171
|
+
return false
|
|
172
|
+
}
|
|
173
|
+
return isColorLight(getStatusBarBackgroundColor(statusBar))
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private fun getStatusBarColorAnimation(statusBarOptions: StatusBarOptions): Animator? {
|
|
177
|
+
if (isEnabled(RNNToggles.TOP_BAR_COLOR_ANIMATION__TABS)) {
|
|
178
|
+
getCurrentStatusBarBackgroundColor()?.let { currentColor ->
|
|
179
|
+
val targetColor = statusBarOptions.backgroundColor
|
|
180
|
+
|
|
181
|
+
if (targetColor.hasValue()) {
|
|
182
|
+
val translucent = statusBarOptions.translucent.isTrue
|
|
183
|
+
return createStatusBarColorAnimation(
|
|
184
|
+
from = currentColor,
|
|
185
|
+
to = targetColor.get(),
|
|
186
|
+
translucent = translucent,
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return null
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private fun createStatusBarColorAnimation(from: Int, to: Int, translucent: Boolean): Animator =
|
|
195
|
+
sbColorAnimator.getAnimator(from, to, translucent).apply {
|
|
196
|
+
addListener(onAnimatorEnd {
|
|
197
|
+
hasPendingColorAnim = false
|
|
198
|
+
})
|
|
199
|
+
hasPendingColorAnim = true
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
private fun getCurrentStatusBarBackgroundColor() =
|
|
203
|
+
getStatusBarColor(window.get())
|
|
204
|
+
|
|
205
|
+
companion object {
|
|
206
|
+
lateinit var instance: StatusBarPresenter
|
|
207
|
+
|
|
208
|
+
fun init(activity: Activity) {
|
|
209
|
+
instance = StatusBarPresenter(activity)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
package com.reactnativenavigation.viewcontrollers.viewcontroller;
|
|
2
2
|
|
|
3
|
+
import static com.reactnativenavigation.utils.ColorUtils.isColorLight;
|
|
4
|
+
|
|
3
5
|
import android.app.Activity;
|
|
4
6
|
import android.graphics.Color;
|
|
5
7
|
import android.graphics.drawable.ColorDrawable;
|
|
@@ -8,27 +10,25 @@ import android.graphics.drawable.LayerDrawable;
|
|
|
8
10
|
import android.view.View;
|
|
9
11
|
import android.view.ViewGroup;
|
|
10
12
|
import android.view.ViewGroup.MarginLayoutParams;
|
|
11
|
-
import android.view.Window;
|
|
12
13
|
|
|
13
14
|
import com.reactnativenavigation.options.NavigationBarOptions;
|
|
14
15
|
import com.reactnativenavigation.options.Options;
|
|
15
16
|
import com.reactnativenavigation.options.OrientationOptions;
|
|
16
17
|
import com.reactnativenavigation.options.StatusBarOptions;
|
|
17
|
-
import com.reactnativenavigation.options.StatusBarOptions.TextColorScheme;
|
|
18
18
|
import com.reactnativenavigation.options.layout.LayoutInsets;
|
|
19
|
-
import com.reactnativenavigation.options.params.Bool;
|
|
20
19
|
import com.reactnativenavigation.utils.SystemUiUtils;
|
|
21
|
-
import com.reactnativenavigation.viewcontrollers.parent.ParentController;
|
|
22
20
|
import com.reactnativenavigation.viewcontrollers.navigator.Navigator;
|
|
21
|
+
import com.reactnativenavigation.viewcontrollers.parent.ParentController;
|
|
22
|
+
import com.reactnativenavigation.viewcontrollers.statusbar.StatusBarPresenter;
|
|
23
23
|
|
|
24
24
|
public class Presenter {
|
|
25
25
|
private final Activity activity;
|
|
26
|
+
|
|
26
27
|
private Options defaultOptions;
|
|
27
28
|
|
|
28
29
|
public Presenter(Activity activity, Options defaultOptions) {
|
|
29
30
|
this.activity = activity;
|
|
30
31
|
this.defaultOptions = defaultOptions;
|
|
31
|
-
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
public void setDefaultOptions(Options defaultOptions) {
|
|
@@ -55,13 +55,13 @@ public class Presenter {
|
|
|
55
55
|
Options withDefaultOptions = options.copy().withDefaultOptions(defaultOptions);
|
|
56
56
|
applyOrientation(withDefaultOptions.layout.orientation);
|
|
57
57
|
applyViewOptions(view, withDefaultOptions);
|
|
58
|
-
applyStatusBarOptions(view, withDefaultOptions);
|
|
58
|
+
applyStatusBarOptions(view, withDefaultOptions.statusBar);
|
|
59
59
|
applyNavigationBarOptions(withDefaultOptions.navigationBar);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
public void onViewBroughtToFront(ViewController<?> viewController, Options options) {
|
|
63
63
|
Options withDefaultOptions = options.copy().withDefaultOptions(defaultOptions);
|
|
64
|
-
applyStatusBarOptions(viewController, withDefaultOptions);
|
|
64
|
+
applyStatusBarOptions(viewController, withDefaultOptions.statusBar);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
private void applyOrientation(OrientationOptions options) {
|
|
@@ -104,101 +104,12 @@ public class Presenter {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
private void applyStatusBarOptions(ViewController viewController,
|
|
108
|
-
|
|
109
|
-
setStatusBarBackgroundColor(statusBar);
|
|
110
|
-
setTextColorScheme(statusBar);
|
|
111
|
-
setTranslucent(statusBar);
|
|
112
|
-
setStatusBarVisible(viewController, statusBar.visible);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
private void setTranslucent(StatusBarOptions options) {
|
|
116
|
-
Window window = activity.getWindow();
|
|
117
|
-
if (options.translucent.isTrue()) {
|
|
118
|
-
SystemUiUtils.setStatusBarTranslucent(window);
|
|
119
|
-
} else if (SystemUiUtils.isTranslucent(window)) {
|
|
120
|
-
SystemUiUtils.clearStatusBarTranslucency(window);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
private void setStatusBarVisible(ViewController viewController, Bool visible) {
|
|
125
|
-
final View view = viewController.view != null ? viewController.view : activity.getWindow().getDecorView();
|
|
126
|
-
if (visible.isFalse()) {
|
|
127
|
-
SystemUiUtils.hideStatusBar(activity.getWindow(), view);
|
|
128
|
-
} else {
|
|
129
|
-
SystemUiUtils.showStatusBar(activity.getWindow(), view);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
private void setStatusBarBackgroundColor(StatusBarOptions statusBar) {
|
|
134
|
-
if (statusBar.backgroundColor.canApplyValue()) {
|
|
135
|
-
final int statusBarBackgroundColor = getStatusBarBackgroundColor(statusBar);
|
|
136
|
-
SystemUiUtils.setStatusBarColor(activity.getWindow(), statusBarBackgroundColor,
|
|
137
|
-
statusBar.translucent.isTrue());
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
private boolean isDarkTextColorScheme(StatusBarOptions statusBar) {
|
|
142
|
-
if (statusBar.textColorScheme == TextColorScheme.Dark) {
|
|
143
|
-
return true;
|
|
144
|
-
} else if (statusBar.textColorScheme == TextColorScheme.Light) {
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
return isColorLight(getStatusBarBackgroundColor(statusBar));
|
|
107
|
+
private void applyStatusBarOptions(ViewController viewController, StatusBarOptions options) {
|
|
108
|
+
StatusBarPresenter.instance.applyOptions(viewController, options);
|
|
149
109
|
}
|
|
150
110
|
|
|
151
|
-
private
|
|
152
|
-
|
|
153
|
-
return statusBar.backgroundColor.get(defaultColor);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
private void setTextColorScheme(StatusBarOptions statusBar) {
|
|
157
|
-
final View view = activity.getWindow().getDecorView();
|
|
158
|
-
//View.post is a Workaround, added to solve internal Samsung
|
|
159
|
-
//Android 9 issues. For more info see https://github.com/wix/react-native-navigation/pull/7231
|
|
160
|
-
view.post(() -> {
|
|
161
|
-
SystemUiUtils.setStatusBarColorScheme(activity.getWindow(), view, isDarkTextColorScheme(statusBar));
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
private void mergeStatusBarOptions(View view, StatusBarOptions statusBar) {
|
|
166
|
-
mergeStatusBarBackgroundColor(statusBar);
|
|
167
|
-
mergeTextColorScheme(statusBar);
|
|
168
|
-
mergeTranslucent(statusBar);
|
|
169
|
-
mergeStatusBarVisible(view, statusBar.visible);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
private void mergeStatusBarBackgroundColor(StatusBarOptions statusBar) {
|
|
173
|
-
if (statusBar.backgroundColor.hasValue()) {
|
|
174
|
-
final int statusBarBackgroundColor = getStatusBarBackgroundColor(statusBar);
|
|
175
|
-
SystemUiUtils.setStatusBarColor(activity.getWindow(), statusBarBackgroundColor,
|
|
176
|
-
statusBar.translucent.isTrue());
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
private void mergeTextColorScheme(StatusBarOptions statusBar) {
|
|
181
|
-
if (!statusBar.textColorScheme.hasValue()) return;
|
|
182
|
-
setTextColorScheme(statusBar);
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
private void mergeTranslucent(StatusBarOptions options) {
|
|
186
|
-
Window window = activity.getWindow();
|
|
187
|
-
if (options.translucent.isTrue()) {
|
|
188
|
-
SystemUiUtils.setStatusBarTranslucent(window);
|
|
189
|
-
} else if (options.translucent.isFalse() && SystemUiUtils.isTranslucent(window)) {
|
|
190
|
-
SystemUiUtils.clearStatusBarTranslucency(window);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
private void mergeStatusBarVisible(View view, Bool visible) {
|
|
195
|
-
if (visible.hasValue()) {
|
|
196
|
-
if (visible.isTrue()) {
|
|
197
|
-
SystemUiUtils.showStatusBar(activity.getWindow(), view);
|
|
198
|
-
} else {
|
|
199
|
-
SystemUiUtils.hideStatusBar(activity.getWindow(), view);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
111
|
+
private void mergeStatusBarOptions(View view, StatusBarOptions statusBarOptions) {
|
|
112
|
+
StatusBarPresenter.instance.mergeOptions(view, statusBarOptions);
|
|
202
113
|
}
|
|
203
114
|
|
|
204
115
|
private void applyNavigationBarOptions(NavigationBarOptions options) {
|
|
@@ -236,16 +147,10 @@ public class Presenter {
|
|
|
236
147
|
}
|
|
237
148
|
}
|
|
238
149
|
|
|
239
|
-
private boolean isColorLight(int color) {
|
|
240
|
-
double darkness = 1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255;
|
|
241
|
-
return darkness < 0.5;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
150
|
public void onConfigurationChanged(ViewController controller, Options options) {
|
|
245
151
|
Options withDefault = options.withDefaultOptions(defaultOptions);
|
|
246
152
|
setNavigationBarBackgroundColor(withDefault.navigationBar);
|
|
247
|
-
|
|
248
|
-
setTextColorScheme(withDefault.statusBar);
|
|
153
|
+
StatusBarPresenter.instance.onConfigurationChanged(withDefault.statusBar);
|
|
249
154
|
applyBackgroundColor(controller, withDefault);
|
|
250
155
|
}
|
|
251
156
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
package com.reactnativenavigation.viewcontrollers.viewcontroller
|
|
2
|
+
|
|
3
|
+
import android.animation.ValueAnimator
|
|
4
|
+
import android.app.Activity
|
|
5
|
+
import com.reactnativenavigation.utils.ColorUtils
|
|
6
|
+
import com.reactnativenavigation.utils.SystemUiUtils
|
|
7
|
+
import com.reactnativenavigation.views.animations.ColorAnimator
|
|
8
|
+
import java.lang.ref.WeakReference
|
|
9
|
+
|
|
10
|
+
private const val STATUS_BAR_TRANSLUCENCY_ALPHA = (SystemUiUtils.STATUS_BAR_HEIGHT_TRANSLUCENCY * 255).toInt()
|
|
11
|
+
|
|
12
|
+
class StatusBarColorAnimator(val activity: Activity) {
|
|
13
|
+
private val colorAnimator = ColorAnimator()
|
|
14
|
+
private val window = WeakReference(activity.window)
|
|
15
|
+
|
|
16
|
+
fun getAnimator(from: Int, to: Int, isTranslucent: Boolean): ValueAnimator =
|
|
17
|
+
colorAnimator.getAnimation(
|
|
18
|
+
from = from,
|
|
19
|
+
to = embedTranslucency(to, isTranslucent)
|
|
20
|
+
).apply {
|
|
21
|
+
addUpdateListener { animation ->
|
|
22
|
+
SystemUiUtils.setStatusBarColor(window.get(), animation.animatedValue as Int)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private fun embedTranslucency(color: Int, isTranslucent: Boolean): Int =
|
|
27
|
+
if (!isTranslucent) color else ColorUtils.setAlpha(color, STATUS_BAR_TRANSLUCENCY_ALPHA)
|
|
28
|
+
}
|