react-native-navigation 7.43.0 → 7.45.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.
Files changed (73) hide show
  1. package/lib/Mock/Components/ComponentScreen.tsx +29 -15
  2. package/lib/Mock/Components/LayoutComponent.tsx +2 -2
  3. package/lib/Mock/index.js +2 -2
  4. package/lib/android/app/build.gradle +1 -0
  5. package/lib/android/app/src/main/java/com/reactnativenavigation/FeatureToggles.kt +62 -0
  6. package/lib/android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java +2 -2
  7. package/lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java +20 -4
  8. package/lib/android/app/src/main/java/com/reactnativenavigation/options/ValueAnimationOptions.kt +3 -3
  9. package/lib/android/app/src/main/java/com/reactnativenavigation/react/ReactView.java +3 -3
  10. package/lib/android/app/src/main/java/com/reactnativenavigation/react/modal/ModalHostLayout.kt +1 -1
  11. package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ColorUtils.java +11 -0
  12. package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactTypefaceUtils.java +3 -2
  13. package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactViewGroup.kt +4 -2
  14. package/lib/android/app/src/main/java/com/reactnativenavigation/utils/StubAnimationListener.kt +19 -0
  15. package/lib/android/app/src/main/java/com/reactnativenavigation/utils/SystemUiUtils.kt +17 -16
  16. package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ViewUtils.java +6 -4
  17. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabPresenter.java +0 -1
  18. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsAnimator.kt +2 -2
  19. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsController.java +20 -13
  20. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java +7 -14
  21. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/component/ComponentPresenter.java +18 -0
  22. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/component/ComponentViewController.java +24 -12
  23. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackController.java +52 -24
  24. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackPresenter.java +20 -10
  25. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/{TopBarAnimator.kt → TopBarAppearanceAnimator.kt} +4 -2
  26. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/TopBarCollapseBehavior.kt +1 -1
  27. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/TopBarController.kt +154 -26
  28. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/statusbar/StatusBarPresenter.kt +212 -0
  29. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/LayoutDirectionApplier.kt +8 -4
  30. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/Presenter.java +12 -107
  31. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/RootPresenter.java +1 -1
  32. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/StatusBarColorAnimator.kt +28 -0
  33. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/ViewController.java +34 -2
  34. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/ViewControllerVisibilityInfo.kt +5 -0
  35. package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/{BaseViewAnimator.kt → BaseViewAppearanceAnimator.kt} +4 -4
  36. package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/ColorAnimator.kt +22 -0
  37. package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/DefaultViewAnimatorCreator.kt +8 -8
  38. package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/ViewAnimatorCreator.kt +2 -2
  39. package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/ViewBkgColorProperty.kt +17 -0
  40. package/lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/BackgroundColorAnimator.kt +6 -4
  41. package/lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/BackgroundColorEvaluator.kt +4 -2
  42. package/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt +6 -6
  43. package/lib/dist/Mock/Application.d.ts +4 -6
  44. package/lib/dist/Mock/Components/BottomTabs.d.ts +9 -13
  45. package/lib/dist/Mock/Components/ComponentScreen.d.ts +5 -7
  46. package/lib/dist/Mock/Components/ComponentScreen.js +10 -3
  47. package/lib/dist/Mock/Components/LayoutComponent.d.ts +9 -13
  48. package/lib/dist/Mock/Components/Modals.d.ts +9 -13
  49. package/lib/dist/Mock/Components/NavigationButton.d.ts +11 -15
  50. package/lib/dist/Mock/Components/Overlays.d.ts +9 -13
  51. package/lib/dist/Mock/Components/Stack.d.ts +9 -13
  52. package/lib/dist/Mock/Components/TopBar.d.ts +7 -9
  53. package/lib/dist/Mock/connect.js +2 -1
  54. package/lib/dist/Mock/index.js +2 -2
  55. package/lib/dist/src/adapters/NativeEventsReceiver.js +1 -1
  56. package/lib/dist/src/adapters/TouchablePreview.d.ts +2 -2
  57. package/lib/dist/src/commands/LayoutType.js +1 -1
  58. package/lib/dist/src/commands/OptionsProcessor.js +8 -1
  59. package/lib/dist/src/components/Modal.d.ts +1 -1
  60. package/lib/dist/src/interfaces/CommandName.js +1 -1
  61. package/lib/dist/src/interfaces/Options.d.ts +33 -3
  62. package/lib/dist/src/interfaces/Options.js +2 -2
  63. package/lib/dist/src/types.d.ts +1 -0
  64. package/lib/ios/BottomTabsBasePresenter.m +3 -2
  65. package/lib/ios/RNNAppDelegate.mm +1 -2
  66. package/lib/ios/RNNConvert.h +2 -0
  67. package/lib/ios/RNNConvert.m +4 -0
  68. package/lib/ios/RNNStackPresenter.m +3 -2
  69. package/lib/src/adapters/NativeEventsReceiver.ts +3 -3
  70. package/lib/src/adapters/TouchablePreview.tsx +3 -3
  71. package/lib/src/commands/OptionsProcessor.ts +13 -2
  72. package/lib/src/interfaces/Options.ts +38 -3
  73. package/package.json +37 -31
@@ -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,15 +1,19 @@
1
1
  package com.reactnativenavigation.viewcontrollers.viewcontroller
2
2
 
3
+ import android.annotation.SuppressLint
3
4
  import com.facebook.react.ReactInstanceManager
4
5
  import com.facebook.react.modules.i18nmanager.I18nUtil
5
6
  import com.reactnativenavigation.options.Options
6
7
 
7
8
  class LayoutDirectionApplier {
8
- fun apply(root: ViewController<*>, options: Options, instanceManager: ReactInstanceManager) {
9
- if (options.layout.direction.hasValue() && instanceManager.currentReactContext != null) {
9
+ @SuppressLint("WrongConstant")
10
+ fun apply(root: ViewController<*>, options: Options) {
11
+ val currentContext = root.view?.context ?: return
12
+
13
+ if (options.layout.direction.hasValue()) {
10
14
  root.activity.window.decorView.layoutDirection = options.layout.direction.get()
11
- I18nUtil.getInstance().allowRTL(instanceManager.currentReactContext, options.layout.direction.isRtl)
12
- I18nUtil.getInstance().forceRTL(instanceManager.currentReactContext, options.layout.direction.isRtl)
15
+ I18nUtil.instance.allowRTL(currentContext, options.layout.direction.isRtl)
16
+ I18nUtil.instance.forceRTL(currentContext, options.layout.direction.isRtl)
13
17
  }
14
18
  }
15
19
  }
@@ -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, Options options) {
108
- StatusBarOptions statusBar = options.copy().withDefaultOptions(defaultOptions).statusBar;
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 int getStatusBarBackgroundColor(StatusBarOptions statusBar) {
152
- int defaultColor = statusBar.visible.isTrueOrUndefined() ? Color.BLACK : Color.TRANSPARENT;
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
- setStatusBarBackgroundColor(withDefault.statusBar);
248
- setTextColorScheme(withDefault.statusBar);
153
+ StatusBarPresenter.instance.onConfigurationChanged(withDefault.statusBar);
249
154
  applyBackgroundColor(controller, withDefault);
250
155
  }
251
156
  }
@@ -35,7 +35,7 @@ public class RootPresenter {
35
35
  }
36
36
 
37
37
  public void setRoot(ViewController appearingRoot, ViewController<?> disappearingRoot, Options defaultOptions, CommandListener listener, ReactInstanceManager reactInstanceManager) {
38
- layoutDirectionApplier.apply(appearingRoot, defaultOptions, reactInstanceManager);
38
+ layoutDirectionApplier.apply(appearingRoot, defaultOptions);
39
39
  rootLayout.addView(appearingRoot.getView(), matchParentWithBehaviour(new BehaviourDelegate(appearingRoot)));
40
40
  Options options = appearingRoot.resolveCurrentOptions(defaultOptions);
41
41
  AnimationOptions enter = options.animations.setRoot.getEnter();
@@ -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
+ }
@@ -3,6 +3,7 @@ package com.reactnativenavigation.viewcontrollers.viewcontroller;
3
3
  import static com.reactnativenavigation.utils.CollectionUtils.forEach;
4
4
  import static com.reactnativenavigation.utils.ObjectUtils.perform;
5
5
 
6
+ import android.animation.Animator;
6
7
  import android.app.Activity;
7
8
  import android.content.res.Configuration;
8
9
  import android.view.View;
@@ -12,11 +13,11 @@ import android.view.ViewTreeObserver;
12
13
 
13
14
  import androidx.annotation.CallSuper;
14
15
  import androidx.annotation.CheckResult;
16
+ import androidx.annotation.NonNull;
15
17
  import androidx.annotation.Nullable;
16
18
  import androidx.annotation.VisibleForTesting;
17
19
  import androidx.coordinatorlayout.widget.CoordinatorLayout;
18
20
 
19
- import com.reactnativenavigation.BuildConfig;
20
21
  import com.reactnativenavigation.options.Options;
21
22
  import com.reactnativenavigation.options.params.Bool;
22
23
  import com.reactnativenavigation.options.params.NullBool;
@@ -113,10 +114,34 @@ public abstract class ViewController<T extends ViewGroup> implements ViewTreeObs
113
114
 
114
115
  public abstract T createView();
115
116
 
117
+ public void onSelected(ViewController<?> previousVC) {
118
+ setVisible();
119
+ }
120
+
121
+ public void onDeselected() {
122
+ setInvisible();
123
+ }
124
+
125
+ public void setVisible() {
126
+ getView().setVisibility(View.VISIBLE);
127
+
128
+ onViewWillAppear();
129
+ onViewDidAppear();
130
+ }
131
+
132
+ public void setInvisible() {
133
+ getView().setVisibility(View.INVISIBLE);
134
+ }
135
+
116
136
  public void setViewVisibilityListener(ViewVisibilityListener viewVisibilityListener) {
117
137
  this.viewVisibilityListener = viewVisibilityListener;
118
138
  }
119
139
 
140
+ @NonNull
141
+ public ViewControllerVisibilityInfo getVisibilityInfo() {
142
+ return new ViewControllerVisibilityInfo(null);
143
+ }
144
+
120
145
  @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
121
146
  public void ensureViewIsCreated() {
122
147
  getView();
@@ -172,7 +197,6 @@ public abstract class ViewController<T extends ViewGroup> implements ViewTreeObs
172
197
  }
173
198
 
174
199
  public void setDefaultOptions(Options defaultOptions) {
175
-
176
200
  }
177
201
 
178
202
  public Activity getActivity() {
@@ -352,6 +376,14 @@ public abstract class ViewController<T extends ViewGroup> implements ViewTreeObs
352
376
 
353
377
  }
354
378
 
379
+ public Animator getPushAnimations(Options appearingOptions) {
380
+ return null;
381
+ }
382
+
383
+ public Animator getPopAnimations(Options appearingOptions, Options disappearingOptions) {
384
+ return null;
385
+ }
386
+
355
387
  protected void runOnPreDraw(Func1<T> task) {
356
388
  if (!isDestroyed) UiUtils.runOnPreDrawOnce(getView(), task);
357
389
  }
@@ -0,0 +1,5 @@
1
+ package com.reactnativenavigation.viewcontrollers.viewcontroller
2
+
3
+ data class TopBarVisibilityInfo(val isShown: Boolean, val solidColor: Int?)
4
+
5
+ data class ViewControllerVisibilityInfo(val topBarVisibilityInfo: TopBarVisibilityInfo?)
@@ -12,7 +12,7 @@ import com.reactnativenavigation.options.animations.ViewAnimationOptions
12
12
  import com.reactnativenavigation.options.params.Bool
13
13
  import com.reactnativenavigation.utils.resetViewProperties
14
14
 
15
- open class BaseViewAnimator<T : View>(
15
+ open class BaseViewAppearanceAnimator<T : View>(
16
16
  private val hideDirection: HideDirection,
17
17
  view: T? = null,
18
18
  private val defaultAnimatorCreator: ViewAnimatorCreator = DefaultViewAnimatorCreator()
@@ -90,16 +90,16 @@ open class BaseViewAnimator<T : View>(
90
90
 
91
91
  fun isAnimatingShow() = showAnimator.isRunning
92
92
 
93
- fun getPushAnimation(animation: ViewAnimationOptions, visible: Bool, additionalDy: Float = 0f): Animator? {
93
+ fun getPushAnimation(animationOpts: ViewAnimationOptions, visible: Bool, additionalDy: Float = 0f): Animator? {
94
94
  if (isOrWillBeVisible && visible.isFalse) {
95
95
  showAnimator.cancel()
96
- hideAnimator = animation.exit.getAnimation(view, defaultAnimatorCreator.getHideAnimator(view, hideDirection, additionalDy))
96
+ hideAnimator = animationOpts.exit.getAnimation(view, defaultAnimatorCreator.getHideAnimator(view, hideDirection, additionalDy))
97
97
  return hideAnimator
98
98
  }
99
99
 
100
100
  if (isOrWillBeHidden && visible.isTrueOrUndefined) {
101
101
  hideAnimator.cancel()
102
- showAnimator = animation.enter.getAnimation(view, defaultAnimatorCreator.getShowAnimator(view, hideDirection, additionalDy))
102
+ showAnimator = animationOpts.enter.getAnimation(view, defaultAnimatorCreator.getShowAnimator(view, hideDirection, additionalDy))
103
103
  return showAnimator
104
104
  }
105
105
 
@@ -0,0 +1,22 @@
1
+ package com.reactnativenavigation.views.animations
2
+
3
+ import android.animation.ObjectAnimator
4
+ import android.animation.ValueAnimator
5
+ import android.view.View
6
+
7
+ class ColorAnimator {
8
+ fun getAnimation(from: Int, to: Int): ValueAnimator = createObjectAnimator(null, from, to)
9
+ fun getAnimation(view: View, from: Int, to: Int): ValueAnimator = createObjectAnimator(view, from, to)
10
+
11
+ private fun createObjectAnimator(view: View?, from: Int, to: Int) =
12
+ if (view == null) {
13
+ ObjectAnimator.ofArgb(from, to)
14
+ } else {
15
+ ObjectAnimator.ofArgb(
16
+ view,
17
+ view.BkgColorProperty,
18
+ from,
19
+ to,
20
+ )
21
+ }
22
+ }
@@ -13,11 +13,11 @@ class DefaultViewAnimatorCreator : ViewAnimatorCreator {
13
13
  }
14
14
 
15
15
  override fun getShowAnimator(
16
- view: View,
17
- hideDirection: BaseViewAnimator.HideDirection,
18
- translationStart: Float
16
+ view: View,
17
+ hideDirection: BaseViewAppearanceAnimator.HideDirection,
18
+ translationStart: Float
19
19
  ): Animator {
20
- val direction = if (hideDirection == BaseViewAnimator.HideDirection.Up) 1 else -1
20
+ val direction = if (hideDirection == BaseViewAppearanceAnimator.HideDirection.Up) 1 else -1
21
21
  return ObjectAnimator.ofFloat(
22
22
  view,
23
23
  View.TRANSLATION_Y,
@@ -30,11 +30,11 @@ class DefaultViewAnimatorCreator : ViewAnimatorCreator {
30
30
  }
31
31
 
32
32
  override fun getHideAnimator(
33
- view: View,
34
- hideDirection: BaseViewAnimator.HideDirection,
35
- additionalDy: Float
33
+ view: View,
34
+ hideDirection: BaseViewAppearanceAnimator.HideDirection,
35
+ additionalDy: Float
36
36
  ): Animator {
37
- val direction = if (hideDirection == BaseViewAnimator.HideDirection.Up) -1 else 1
37
+ val direction = if (hideDirection == BaseViewAppearanceAnimator.HideDirection.Up) -1 else 1
38
38
  return ObjectAnimator.ofFloat(
39
39
  view,
40
40
  View.TRANSLATION_Y,
@@ -4,6 +4,6 @@ import android.animation.Animator
4
4
  import android.view.View
5
5
 
6
6
  interface ViewAnimatorCreator {
7
- fun getShowAnimator(view: View, hideDirection: BaseViewAnimator.HideDirection, translationStart: Float): Animator
8
- fun getHideAnimator(view: View, hideDirection: BaseViewAnimator.HideDirection, additionalDy: Float): Animator
7
+ fun getShowAnimator(view: View, hideDirection: BaseViewAppearanceAnimator.HideDirection, translationStart: Float): Animator
8
+ fun getHideAnimator(view: View, hideDirection: BaseViewAppearanceAnimator.HideDirection, additionalDy: Float): Animator
9
9
  }
@@ -0,0 +1,17 @@
1
+ package com.reactnativenavigation.views.animations
2
+
3
+ import android.graphics.drawable.ColorDrawable
4
+ import android.util.Property
5
+ import android.view.View
6
+
7
+ val View.BkgColorProperty: Property<View, Int>
8
+ // TODO Replace Property with IntProperty (Requires SDK≥24)
9
+ get() = object: Property<View, Int>(Int::class.java, "bkgColor") {
10
+ override fun set(view: View, value: Int) {
11
+ (view.background as ColorDrawable).color = value
12
+ }
13
+
14
+ override fun get(view: View): Int {
15
+ return (view.background as ColorDrawable).color
16
+ }
17
+ }