react-native-navigation 7.43.0 → 8.0.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 (67) 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 +60 -0
  6. package/lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java +20 -4
  7. package/lib/android/app/src/main/java/com/reactnativenavigation/options/ValueAnimationOptions.kt +3 -3
  8. package/lib/android/app/src/main/java/com/reactnativenavigation/react/ReactView.java +3 -3
  9. package/lib/android/app/src/main/java/com/reactnativenavigation/react/modal/ModalHostLayout.kt +1 -1
  10. package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactTypefaceUtils.java +3 -2
  11. package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactViewGroup.kt +4 -2
  12. package/lib/android/app/src/main/java/com/reactnativenavigation/utils/StubAnimationListener.kt +19 -0
  13. package/lib/android/app/src/main/java/com/reactnativenavigation/utils/SystemUiUtils.kt +16 -10
  14. package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ViewUtils.java +6 -4
  15. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/bottomtabs/BottomTabsAnimator.kt +2 -2
  16. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java +7 -14
  17. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/component/ComponentViewController.java +37 -13
  18. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackController.java +24 -11
  19. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/StackPresenter.java +13 -10
  20. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/statusbar/StatusBarController.kt +9 -0
  21. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/statusbar/StatusBarPresenter.kt +9 -0
  22. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/{TopBarAnimator.kt → TopBarAppearanceAnimator.kt} +4 -2
  23. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/TopBarCollapseBehavior.kt +1 -1
  24. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/stack/topbar/TopBarController.kt +122 -27
  25. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/LayoutDirectionApplier.kt +8 -4
  26. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/Presenter.java +79 -6
  27. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/RootPresenter.java +1 -1
  28. package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/ViewController.java +5 -0
  29. package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/{BaseViewAnimator.kt → BaseViewAppearanceAnimator.kt} +4 -4
  30. package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/ColorAnimator.kt +22 -0
  31. package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/DefaultViewAnimatorCreator.kt +8 -8
  32. package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/ViewAnimatorCreator.kt +2 -2
  33. package/lib/android/app/src/main/java/com/reactnativenavigation/views/animations/ViewBkgColorProperty.kt +17 -0
  34. package/lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/BackgroundColorAnimator.kt +6 -4
  35. package/lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/BackgroundColorEvaluator.kt +4 -2
  36. package/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt +6 -6
  37. package/lib/dist/Mock/Application.d.ts +4 -6
  38. package/lib/dist/Mock/Components/BottomTabs.d.ts +9 -13
  39. package/lib/dist/Mock/Components/ComponentScreen.d.ts +5 -7
  40. package/lib/dist/Mock/Components/ComponentScreen.js +10 -3
  41. package/lib/dist/Mock/Components/LayoutComponent.d.ts +9 -13
  42. package/lib/dist/Mock/Components/Modals.d.ts +9 -13
  43. package/lib/dist/Mock/Components/NavigationButton.d.ts +11 -15
  44. package/lib/dist/Mock/Components/Overlays.d.ts +9 -13
  45. package/lib/dist/Mock/Components/Stack.d.ts +9 -13
  46. package/lib/dist/Mock/Components/TopBar.d.ts +7 -9
  47. package/lib/dist/Mock/connect.js +2 -1
  48. package/lib/dist/Mock/index.js +2 -2
  49. package/lib/dist/src/adapters/NativeEventsReceiver.js +1 -1
  50. package/lib/dist/src/adapters/TouchablePreview.d.ts +2 -2
  51. package/lib/dist/src/commands/LayoutType.js +1 -1
  52. package/lib/dist/src/commands/OptionsProcessor.js +8 -1
  53. package/lib/dist/src/components/Modal.d.ts +1 -1
  54. package/lib/dist/src/interfaces/CommandName.js +1 -1
  55. package/lib/dist/src/interfaces/Options.d.ts +33 -3
  56. package/lib/dist/src/interfaces/Options.js +2 -2
  57. package/lib/dist/src/types.d.ts +1 -0
  58. package/lib/ios/BottomTabsBasePresenter.m +3 -2
  59. package/lib/ios/RNNAppDelegate.mm +1 -2
  60. package/lib/ios/RNNConvert.h +2 -0
  61. package/lib/ios/RNNConvert.m +4 -0
  62. package/lib/ios/RNNStackPresenter.m +3 -2
  63. package/lib/src/adapters/NativeEventsReceiver.ts +3 -3
  64. package/lib/src/adapters/TouchablePreview.tsx +3 -3
  65. package/lib/src/commands/OptionsProcessor.ts +13 -2
  66. package/lib/src/interfaces/Options.ts +38 -3
  67. package/package.json +37 -31
@@ -1,6 +1,6 @@
1
1
  import React, { Component } from 'react';
2
- import { View, Text, TouchableOpacity, Image, ImageURISource} from 'react-native';
3
- import { Navigation, ImageResource} from 'react-native-navigation';
2
+ import { View, Text, TouchableOpacity, Image, ImageURISource } from 'react-native';
3
+ import { Navigation, ImageResource } from 'react-native-navigation';
4
4
  import { ComponentProps } from '../ComponentProps';
5
5
  import { VISIBLE_SCREEN_TEST_ID } from '../constants';
6
6
  import { LayoutStore } from '../Stores/LayoutStore';
@@ -10,8 +10,7 @@ import { events } from '../Stores/EventsStore';
10
10
  import _ from 'lodash';
11
11
  import { switchTabByIndex } from '../actions/layoutActions';
12
12
 
13
-
14
- function isURISource(src: ImageResource| undefined): src is ImageURISource {
13
+ function isURISource(src: ImageResource | undefined): src is ImageURISource {
15
14
  return !!src && typeof src === 'object' && 'uri' in src;
16
15
  }
17
16
 
@@ -36,12 +35,15 @@ export const ComponentScreen = connect(
36
35
  if (bottomTabsOptions?.visible === false) return null;
37
36
  const buttons = bottomTabs!.children!.map((child, i) => {
38
37
  const bottomTabOptions = child.resolveOptions().bottomTab;
39
- const icon = (bottomTabs as any).selectedIndex === i ? bottomTabOptions?.selectedIcon : bottomTabOptions?.icon;
38
+ const icon =
39
+ (bottomTabs as any).selectedIndex === i
40
+ ? bottomTabOptions?.selectedIcon
41
+ : bottomTabOptions?.icon;
40
42
  const iconURI = isURISource(icon) ? icon.uri : undefined;
41
43
  return (
42
44
  <View key={`tab-${i}`}>
43
45
  <TouchableOpacity
44
- style={{padding:10}}
46
+ style={{ padding: 10 }}
45
47
  testID={bottomTabOptions?.testID}
46
48
  onPress={() => {
47
49
  events.invokeBottomTabPressed({
@@ -51,22 +53,34 @@ export const ComponentScreen = connect(
51
53
  switchTabByIndex(this.props.layoutNode.getBottomTabs(), i);
52
54
  }}
53
55
  >
54
- <View style={{justifyContent: 'center', alignItems: 'center'}}>
55
- <Text>{bottomTabOptions?.badge}</Text>
56
- {iconURI && <Image style={{width: 18, height: 18, marginBottom: 5}} source={{uri: iconURI}}/>}
57
- <Text style={{fontSize: 12}}>{bottomTabOptions?.text || ''}</Text>
58
- </View>
56
+ <View style={{ justifyContent: 'center', alignItems: 'center' }}>
57
+ <Text>{bottomTabOptions?.badge}</Text>
58
+ {iconURI && (
59
+ <Image
60
+ style={{ width: 18, height: 18, marginBottom: 5 }}
61
+ source={{ uri: iconURI }}
62
+ />
63
+ )}
64
+ <Text style={{ fontSize: 12 }}>{bottomTabOptions?.text || ''}</Text>
65
+ </View>
59
66
  </TouchableOpacity>
60
67
  </View>
61
68
  );
62
69
  });
63
70
 
64
71
  return (
65
- <View
66
- testID={bottomTabsOptions?.testID}
67
- style={{flexDirection: 'row',justifyContent: 'center', width: '100%', backgroundColor: '#F0F2F5'}}>
72
+ <View
73
+ testID={bottomTabsOptions?.testID}
74
+ style={{
75
+ flexDirection: 'row',
76
+ justifyContent: 'center',
77
+ width: '100%',
78
+ backgroundColor: '#F0F2F5',
79
+ }}
80
+ >
68
81
  {buttons}
69
- </View>);
82
+ </View>
83
+ );
70
84
  }
71
85
 
72
86
  render() {
@@ -19,8 +19,8 @@ export const LayoutComponent = class extends Component<ComponentProps> {
19
19
  return <View />;
20
20
  }
21
21
  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
22
- const err = new Error(
23
- `Error while trying to render layout ${this.props.layoutNode.nodeId} of type ${this.props.layoutNode.type}: ${error}\n${errorInfo?.componentStack}`,
22
+ const err = new Error(
23
+ `Error while trying to render layout ${this.props.layoutNode.nodeId} of type ${this.props.layoutNode.type}: ${error}\n${errorInfo?.componentStack}`
24
24
  );
25
25
  (err as any).cause = error;
26
26
  throw err;
package/lib/Mock/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ApplicationMock = void 0;
4
- exports.mockNativeComponents = mockNativeComponents;
3
+ exports.mockNativeComponents = exports.ApplicationMock = void 0;
5
4
  const tslib_1 = require("tslib");
6
5
  exports.ApplicationMock = require('./Application').Application;
7
6
  tslib_1.__exportStar(require("./constants"), exports);
@@ -12,3 +11,4 @@ function mockNativeComponents() {
12
11
  const { Navigation } = require('react-native-navigation');
13
12
  Navigation.mockNativeComponents(new NativeCommandsSender(), new NativeEventsReceiver(), new AppRegistryService());
14
13
  }
14
+ exports.mockNativeComponents = mockNativeComponents;
@@ -20,6 +20,7 @@ def DEFAULT_KOTLIN_STDLIB = 'kotlin-stdlib-jdk8'
20
20
  def kotlinVersion = safeExtGet("RNNKotlinVersion", DEFAULT_KOTLIN_VERSION)
21
21
  def kotlinStdlib = safeExtGet('RNNKotlinStdlib',DEFAULT_KOTLIN_STDLIB )
22
22
  def kotlinCoroutinesCore = safeExtGet('RNNKotlinCoroutinesCore', '1.5.2')
23
+
23
24
  android {
24
25
  namespace 'com.reactnativenavigation'
25
26
  compileSdkVersion safeExtGetFallbackLowerBound('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
@@ -0,0 +1,60 @@
1
+ package com.reactnativenavigation
2
+
3
+ import androidx.annotation.VisibleForTesting
4
+
5
+ enum class RNNToggles {
6
+ TOP_BAR_COLOR_ANIMATION,
7
+ }
8
+
9
+ private val ToggleDefaults = mapOf(
10
+ RNNToggles.TOP_BAR_COLOR_ANIMATION to false
11
+ )
12
+
13
+ object RNNFeatureToggles {
14
+ private var init = false
15
+ private var toggles = mutableMapOf<RNNToggles, Boolean>()
16
+
17
+ @JvmStatic
18
+ fun init() {
19
+ assertNotInitialized()
20
+
21
+ init = true
22
+ toggles = ToggleDefaults.toMutableMap()
23
+ }
24
+
25
+ @JvmStatic
26
+ fun init(overrides: Map<RNNToggles, Boolean>) {
27
+ init()
28
+ this.toggles.putAll(overrides)
29
+ }
30
+
31
+ @JvmStatic
32
+ fun init(vararg overrides: Pair<RNNToggles, Boolean>) {
33
+ init(mapOf(*overrides))
34
+ }
35
+
36
+ @JvmStatic
37
+ fun isEnabled(toggleName: RNNToggles): Boolean {
38
+ assertInitialized()
39
+ return toggles.getOrElse(toggleName) { false }
40
+ }
41
+
42
+ @VisibleForTesting
43
+ @JvmStatic
44
+ fun clear() {
45
+ init = false
46
+ toggles.clear()
47
+ }
48
+
49
+ private fun assertNotInitialized() {
50
+ if (init) {
51
+ throw IllegalStateException("FeatureToggles already initialized")
52
+ }
53
+ }
54
+
55
+ private fun assertInitialized() {
56
+ if (!init) {
57
+ throw IllegalStateException("FeatureToggles not initialized")
58
+ }
59
+ }
60
+ }
@@ -4,10 +4,13 @@ import android.app.Application;
4
4
 
5
5
  import com.facebook.react.ReactApplication;
6
6
  import com.facebook.react.ReactNativeHost;
7
+ import com.facebook.react.soloader.OpenSourceMergedSoMapping;
7
8
  import com.facebook.soloader.SoLoader;
8
9
  import com.reactnativenavigation.react.ReactGateway;
9
10
  import com.reactnativenavigation.viewcontrollers.externalcomponent.ExternalComponentCreator;
10
11
 
12
+ import java.util.Collections;
13
+ import java.io.IOException;
11
14
  import java.util.HashMap;
12
15
  import java.util.Map;
13
16
 
@@ -15,15 +18,28 @@ import androidx.annotation.NonNull;
15
18
 
16
19
  public abstract class NavigationApplication extends Application implements ReactApplication {
17
20
 
18
- private ReactGateway reactGateway;
19
21
  public static NavigationApplication instance;
20
- final Map<String, ExternalComponentCreator> externalComponents = new HashMap<>();
22
+
23
+ private final Map<String, ExternalComponentCreator> externalComponents = new HashMap<>();
24
+ private ReactGateway reactGateway;
25
+
26
+ public NavigationApplication() {
27
+ this(Collections.emptyMap());
28
+ }
29
+
30
+ public NavigationApplication(Map<RNNToggles, Boolean> featureToggleOverrides) {
31
+ instance = this;
32
+ RNNFeatureToggles.init(featureToggleOverrides);
33
+ }
21
34
 
22
35
  @Override
23
36
  public void onCreate() {
24
37
  super.onCreate();
25
- instance = this;
26
- SoLoader.init(this, false);
38
+ try {
39
+ SoLoader.init(this, OpenSourceMergedSoMapping.INSTANCE);
40
+ } catch (IOException e) {
41
+ throw new RuntimeException(e);
42
+ }
27
43
  reactGateway = createReactGateway();
28
44
  }
29
45
 
@@ -50,9 +50,9 @@ class ValueAnimationOptions {
50
50
  to += this.to[animationValueAccessor!!(view)]
51
51
  }
52
52
  val animator = ObjectAnimator.ofFloat(view,
53
- animProp,
54
- from,
55
- to
53
+ animProp,
54
+ from,
55
+ to
56
56
  )
57
57
  animator.interpolator = interpolator
58
58
  if (duration.hasValue()) animator.duration = duration.get().toLong()
@@ -5,6 +5,8 @@ import android.content.Context;
5
5
  import android.os.Bundle;
6
6
  import android.view.MotionEvent;
7
7
 
8
+ import androidx.annotation.RestrictTo;
9
+
8
10
  import com.facebook.react.ReactInstanceManager;
9
11
  import com.facebook.react.ReactRootView;
10
12
  import com.facebook.react.bridge.ReactContext;
@@ -12,14 +14,12 @@ import com.facebook.react.config.ReactFeatureFlags;
12
14
  import com.facebook.react.uimanager.JSTouchDispatcher;
13
15
  import com.facebook.react.uimanager.UIManagerModule;
14
16
  import com.facebook.react.uimanager.events.EventDispatcher;
15
- import com.reactnativenavigation.viewcontrollers.viewcontroller.ScrollEventListener;
16
17
  import com.reactnativenavigation.react.events.ComponentType;
17
18
  import com.reactnativenavigation.react.events.EventEmitter;
18
19
  import com.reactnativenavigation.viewcontrollers.viewcontroller.IReactView;
20
+ import com.reactnativenavigation.viewcontrollers.viewcontroller.ScrollEventListener;
19
21
  import com.reactnativenavigation.views.component.Renderable;
20
22
 
21
- import androidx.annotation.RestrictTo;
22
-
23
23
  @SuppressLint("ViewConstructor")
24
24
  public class ReactView extends ReactRootView implements IReactView, Renderable {
25
25
 
@@ -34,7 +34,7 @@ open class ModalHostLayout(reactContext: ThemedReactContext) : ViewGroup(reactCo
34
34
  }
35
35
 
36
36
  @TargetApi(23)
37
- override fun dispatchProvideStructure(structure: ViewStructure?) {
37
+ override fun dispatchProvideStructure(structure: ViewStructure) {
38
38
  mHostView.dispatchProvideStructure(structure)
39
39
  }
40
40
 
@@ -18,6 +18,7 @@ import android.graphics.Typeface;
18
18
  import android.text.TextUtils;
19
19
  import androidx.annotation.Nullable;
20
20
  import com.facebook.react.bridge.ReadableArray;
21
+ import com.facebook.react.common.ReactConstants;
21
22
  import com.facebook.react.views.text.ReactFontManager;
22
23
  import com.facebook.react.views.text.ReactTextShadowNode;
23
24
  import java.util.ArrayList;
@@ -96,12 +97,12 @@ public class ReactTypefaceUtils {
96
97
 
97
98
  int want = 0;
98
99
  if ((weight == Typeface.BOLD)
99
- || ((oldStyle & Typeface.BOLD) != 0 && weight == ReactTextShadowNode.UNSET)) {
100
+ || ((oldStyle & Typeface.BOLD) != 0 && weight == ReactConstants.UNSET)) {
100
101
  want |= Typeface.BOLD;
101
102
  }
102
103
 
103
104
  if ((style == Typeface.ITALIC)
104
- || ((oldStyle & Typeface.ITALIC) != 0 && style == ReactTextShadowNode.UNSET)) {
105
+ || ((oldStyle & Typeface.ITALIC) != 0 && style == ReactConstants.UNSET)) {
105
106
  want |= Typeface.ITALIC;
106
107
  }
107
108
 
@@ -1,7 +1,9 @@
1
1
  package com.reactnativenavigation.utils
2
2
 
3
- import com.facebook.react.views.view.ReactViewBackgroundDrawable
3
+ import com.facebook.react.common.annotations.UnstableReactNativeAPI
4
+ import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable
4
5
  import com.facebook.react.views.view.ReactViewGroup
5
6
 
7
+ @OptIn(UnstableReactNativeAPI::class)
6
8
  val ReactViewGroup.borderRadius: Float
7
- get() = (background as? ReactViewBackgroundDrawable)?.fullBorderRadius ?: 0f
9
+ get() = (background as? CSSBackgroundDrawable)?.fullBorderWidth ?: 0f
@@ -0,0 +1,19 @@
1
+ package com.reactnativenavigation.utils
2
+
3
+ import android.animation.Animator
4
+
5
+ open class StubAnimationListener: Animator.AnimatorListener {
6
+ override fun onAnimationStart(animation: Animator) {}
7
+ override fun onAnimationEnd(animation: Animator) {}
8
+ override fun onAnimationCancel(animation: Animator) {}
9
+ override fun onAnimationRepeat(animation: Animator) {}
10
+
11
+ companion object {
12
+ @JvmStatic
13
+ fun onAnimatorEnd(onEnd: (animation: Animator) -> Unit) = object: StubAnimationListener() {
14
+ override fun onAnimationEnd(animation: Animator) {
15
+ onEnd(animation)
16
+ }
17
+ }
18
+ }
19
+ }
@@ -121,19 +121,25 @@ object SystemUiUtils {
121
121
  @ColorInt color: Int,
122
122
  translucent: Boolean
123
123
  ) {
124
- val opaqueColor = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
125
- Color.BLACK
126
- }else{
127
- val colorAlpha = Color.alpha(color)
128
- val alpha = if (translucent && colorAlpha == 255) STATUS_BAR_HEIGHT_TRANSLUCENCY else colorAlpha/255.0f
129
- val red: Int = Color.red(color)
130
- val green: Int = Color.green(color)
131
- val blue: Int = Color.blue(color)
132
- Color.argb(ceil(alpha * 255).toInt(), red, green, blue)
133
- }
124
+ val opaqueColor =
125
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
126
+ Color.BLACK
127
+ } else {
128
+ val colorAlpha = Color.alpha(color)
129
+ val alpha = if (translucent && colorAlpha == 255) STATUS_BAR_HEIGHT_TRANSLUCENCY else colorAlpha/255.0f
130
+ val red: Int = Color.red(color)
131
+ val green: Int = Color.green(color)
132
+ val blue: Int = Color.blue(color)
133
+ Color.argb(ceil(alpha * 255).toInt(), red, green, blue)
134
+ }
134
135
  window?.statusBarColor = opaqueColor
135
136
  }
136
137
 
138
+ @JvmStatic
139
+ fun getStatusBarColor(window: Window?): Int? {
140
+ return window?.statusBarColor
141
+ }
142
+
137
143
  @JvmStatic
138
144
  fun hideStatusBar(window: Window?, view: View) {
139
145
  window?.let {
@@ -5,8 +5,6 @@ import android.view.View;
5
5
  import android.view.ViewGroup;
6
6
  import android.view.ViewParent;
7
7
 
8
- import com.facebook.react.views.view.ReactViewBackgroundDrawable;
9
-
10
8
  import java.util.ArrayList;
11
9
  import java.util.List;
12
10
 
@@ -14,6 +12,9 @@ import androidx.annotation.Nullable;
14
12
 
15
13
  import static com.reactnativenavigation.utils.ObjectUtils.perform;
16
14
 
15
+ import com.facebook.react.common.annotations.UnstableReactNativeAPI;
16
+ import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable;
17
+
17
18
  public class ViewUtils {
18
19
  @Nullable
19
20
  public static <T extends View> T findChildByClass(ViewGroup root, Class<T> clazz) {
@@ -107,9 +108,10 @@ public class ViewUtils {
107
108
  return ((ViewGroup) parent).indexOfChild(view);
108
109
  }
109
110
 
111
+ @UnstableReactNativeAPI
110
112
  public static int getBackgroundColor(View view) {
111
- if (view.getBackground() instanceof ReactViewBackgroundDrawable) {
112
- return ((ReactViewBackgroundDrawable) view.getBackground()).getColor();
113
+ if (view.getBackground() instanceof CSSBackgroundDrawable) {
114
+ return ((CSSBackgroundDrawable) view.getBackground()).getColor();
113
115
  }
114
116
  throw new RuntimeException(view.getBackground().getClass().getSimpleName() + " is not ReactViewBackgroundDrawable");
115
117
  }
@@ -1,9 +1,9 @@
1
1
  package com.reactnativenavigation.viewcontrollers.bottomtabs
2
2
 
3
- import com.reactnativenavigation.views.animations.BaseViewAnimator
3
+ import com.reactnativenavigation.views.animations.BaseViewAppearanceAnimator
4
4
  import com.reactnativenavigation.views.bottomtabs.BottomTabs
5
5
 
6
- class BottomTabsAnimator(view: BottomTabs? = null) : BaseViewAnimator<BottomTabs>(HideDirection.Down, view) {
6
+ class BottomTabsAnimator(view: BottomTabs? = null) : BaseViewAppearanceAnimator<BottomTabs>(HideDirection.Down, view) {
7
7
  override fun onShowAnimationEnd() {
8
8
  view.restoreBottomNavigation(false)
9
9
  }
@@ -2,30 +2,23 @@ package com.reactnativenavigation.viewcontrollers.child;
2
2
 
3
3
  import android.app.Activity;
4
4
  import android.content.res.Configuration;
5
- import android.os.Build;
6
- import android.util.Log;
7
5
  import android.view.View;
8
6
  import android.view.ViewGroup;
9
- import android.view.WindowInsets;
7
+
8
+ import androidx.annotation.CallSuper;
9
+ import androidx.core.view.ViewCompat;
10
+ import androidx.core.view.WindowInsetsCompat;
10
11
 
11
12
  import com.reactnativenavigation.options.Options;
12
- import com.reactnativenavigation.utils.LogKt;
13
- import com.reactnativenavigation.viewcontrollers.parent.ParentController;
14
- import com.reactnativenavigation.viewcontrollers.viewcontroller.Presenter;
15
- import com.reactnativenavigation.viewcontrollers.viewcontroller.NoOpYellowBoxDelegate;
16
13
  import com.reactnativenavigation.viewcontrollers.navigator.Navigator;
14
+ import com.reactnativenavigation.viewcontrollers.viewcontroller.NoOpYellowBoxDelegate;
15
+ import com.reactnativenavigation.viewcontrollers.viewcontroller.Presenter;
17
16
  import com.reactnativenavigation.viewcontrollers.viewcontroller.ViewController;
18
17
  import com.reactnativenavigation.viewcontrollers.viewcontroller.overlay.ViewControllerOverlay;
19
18
  import com.reactnativenavigation.views.component.Component;
20
19
 
21
- import androidx.annotation.CallSuper;
22
- import androidx.core.graphics.Insets;
23
- import androidx.core.view.ViewCompat;
24
- import androidx.core.view.WindowCompat;
25
- import androidx.core.view.WindowInsetsCompat;
26
-
27
20
  public abstract class ChildController<T extends ViewGroup> extends ViewController<T> {
28
- private final Presenter presenter;
21
+ protected final Presenter presenter;
29
22
  private final ChildControllersRegistry childRegistry;
30
23
 
31
24
  public ChildControllersRegistry getChildRegistry() {
@@ -1,28 +1,29 @@
1
1
  package com.reactnativenavigation.viewcontrollers.component;
2
2
 
3
+ import static com.reactnativenavigation.utils.ObjectUtils.perform;
4
+
5
+ import android.animation.Animator;
3
6
  import android.app.Activity;
4
7
  import android.content.res.Configuration;
5
8
  import android.view.View;
6
9
 
7
- import com.reactnativenavigation.utils.LogKt;
8
- import com.reactnativenavigation.viewcontrollers.viewcontroller.ScrollEventListener;
9
- import com.reactnativenavigation.options.Options;
10
- import com.reactnativenavigation.viewcontrollers.viewcontroller.Presenter;
11
- import com.reactnativenavigation.utils.SystemUiUtils;
12
- import com.reactnativenavigation.viewcontrollers.viewcontroller.ReactViewCreator;
13
- import com.reactnativenavigation.viewcontrollers.child.ChildController;
14
- import com.reactnativenavigation.viewcontrollers.child.ChildControllersRegistry;
15
- import com.reactnativenavigation.viewcontrollers.viewcontroller.ViewController;
16
- import com.reactnativenavigation.views.component.ComponentLayout;
17
-
18
10
  import androidx.annotation.NonNull;
11
+ import androidx.annotation.Nullable;
19
12
  import androidx.core.graphics.Insets;
20
13
  import androidx.core.view.ViewCompat;
21
14
  import androidx.core.view.WindowInsetsCompat;
22
15
 
23
- import static com.reactnativenavigation.utils.ObjectUtils.perform;
16
+ import com.reactnativenavigation.options.Options;
17
+ import com.reactnativenavigation.utils.SystemUiUtils;
18
+ import com.reactnativenavigation.viewcontrollers.child.ChildController;
19
+ import com.reactnativenavigation.viewcontrollers.child.ChildControllersRegistry;
20
+ import com.reactnativenavigation.viewcontrollers.stack.statusbar.StatusBarController;
21
+ import com.reactnativenavigation.viewcontrollers.viewcontroller.Presenter;
22
+ import com.reactnativenavigation.viewcontrollers.viewcontroller.ReactViewCreator;
23
+ import com.reactnativenavigation.viewcontrollers.viewcontroller.ScrollEventListener;
24
+ import com.reactnativenavigation.views.component.ComponentLayout;
24
25
 
25
- public class ComponentViewController extends ChildController<ComponentLayout> {
26
+ public class ComponentViewController extends ChildController<ComponentLayout> implements StatusBarController {
26
27
  private final String componentName;
27
28
  private final ComponentPresenter presenter;
28
29
  private final ReactViewCreator viewCreator;
@@ -64,6 +65,29 @@ public class ComponentViewController extends ChildController<ComponentLayout> {
64
65
  presenter.setDefaultOptions(defaultOptions);
65
66
  }
66
67
 
68
+ @Override
69
+ public StatusBarController getStatusBarController() {
70
+ return this;
71
+ }
72
+
73
+ @Nullable
74
+ @Override
75
+ public Animator getStatusBarPushAnimation(@NonNull Options appearingOptions) {
76
+ if (super.presenter != null) {
77
+ return super.presenter.getStatusBarPushAnimation(appearingOptions);
78
+ }
79
+ return null;
80
+ }
81
+
82
+ @Nullable
83
+ @Override
84
+ public Animator getStatusBarPopAnimation(@NonNull Options appearingOptions, @NonNull Options disappearingOptions) {
85
+ if (super.presenter != null) {
86
+ return super.presenter.getStatusBarPopAnimation(appearingOptions, disappearingOptions);
87
+ }
88
+ return null;
89
+ }
90
+
67
91
  @Override
68
92
  public ScrollEventListener getScrollEventListener() {
69
93
  return perform(view, null, ComponentLayout::getScrollEventListener);
@@ -159,16 +159,19 @@ public class StackController extends ParentController<StackLayout> {
159
159
  listener.onError("A stack can't contain two children with the same id: " + child.getId());
160
160
  return;
161
161
  }
162
- final ViewController<?> toRemove = stack.peek();
163
- if (size() > 0) backButtonHelper.addToPushedChild(child);
164
- child.setParentController(this);
165
- stack.push(child.getId(), child);
166
- if (!isViewCreated()) return;
162
+
163
+ final ViewController<?> toRemove = pushChildToStack(child);
164
+
165
+ if (!isViewCreated()) {
166
+ return;
167
+ }
168
+
167
169
  Options resolvedOptions = resolveCurrentOptions(presenter.getDefaultOptions());
168
- addChildToStack(child, resolvedOptions);
170
+ updateChildLayout(child, resolvedOptions);
171
+
169
172
  if (toRemove != null) {
170
- StackAnimationOptions animation = resolvedOptions.animations.push;
171
- if (animation.enabled.isTrueOrUndefined()) {
173
+ StackAnimationOptions animOptions = resolvedOptions.animations.push;
174
+ if (animOptions.enabled.isTrueOrUndefined()) {
172
175
  animator.push(
173
176
  child,
174
177
  toRemove,
@@ -195,7 +198,17 @@ public class StackController extends ParentController<StackLayout> {
195
198
  listener.onSuccess(toAdd.getId());
196
199
  }
197
200
 
198
- private void addChildToStack(ViewController<?> child, Options resolvedOptions) {
201
+ private ViewController<?> pushChildToStack(ViewController<?> child) {
202
+ final ViewController<?> toRemove = stack.peek();
203
+
204
+ if (size() > 0) backButtonHelper.addToPushedChild(child);
205
+
206
+ child.setParentController(this);
207
+ stack.push(child.getId(), child);
208
+ return toRemove;
209
+ }
210
+
211
+ private void updateChildLayout(ViewController<?> child, Options resolvedOptions) {
199
212
  child.setWaitForRender(resolvedOptions.animations.push.waitForRender);
200
213
  if (size() == 1) presenter.applyInitialChildLayoutOptions(resolvedOptions);
201
214
  getView().addView(child.getView(), getView().getChildCount() - 1, matchParentWithBehaviour(new StackBehaviour(this)));
@@ -222,7 +235,7 @@ public class StackController extends ParentController<StackLayout> {
222
235
  child.setParentController(this);
223
236
  stack.push(child.getId(), child);
224
237
  Options resolvedOptions = resolveCurrentOptions(presenter.getDefaultOptions());
225
- addChildToStack(child, resolvedOptions);
238
+ updateChildLayout(child, resolvedOptions);
226
239
 
227
240
  CommandListener listenerAdapter = new CommandListenerAdapter() {
228
241
  @Override
@@ -316,7 +329,7 @@ public class StackController extends ParentController<StackLayout> {
316
329
  appearing,
317
330
  disappearing,
318
331
  disappearingOptions,
319
- presenter.getAdditionalPopAnimations(appearingOptions, disappearingOptions),
332
+ presenter.getAdditionalPopAnimations(appearingOptions, disappearingOptions, appearing),
320
333
  () -> finishPopping(appearing, disappearing, listener)
321
334
  );
322
335
  } else {
@@ -233,7 +233,7 @@ public class StackPresenter {
233
233
 
234
234
  topBar.setBorderHeight(topBarOptions.borderHeight.get(0d));
235
235
  topBar.setBorderColor(topBarOptions.borderColor.get(DEFAULT_BORDER_COLOR));
236
- topBar.setBackgroundColor(topBarOptions.background.color.get(Color.WHITE));
236
+ topBarController.setBackgroundColor(topBarOptions, Color.WHITE);
237
237
 
238
238
  if (topBarOptions.background.component.hasValue()) {
239
239
  View createdComponent = findBackgroundComponent(topBarOptions.background.component);
@@ -417,18 +417,23 @@ public class StackPresenter {
417
417
  }
418
418
  }
419
419
 
420
- public List<Animator> getAdditionalPushAnimations(StackController stack, ViewController<?> appearing,
420
+ public List<Animator> getAdditionalPushAnimations(
421
+ StackController stack,
422
+ ViewController<?> appearingCtrl,
421
423
  Options appearingOptions) {
422
424
  return CollectionUtils.asList(
423
- topBarController.getPushAnimation(appearingOptions,
424
- getTopBarTranslationAnimationDelta(stack, appearing)),
425
- perform(bottomTabsController, null, btc -> btc.getPushAnimation(appearingOptions)));
425
+ topBarController.getPushAnimation(appearingOptions, getTopBarTranslationAnimationDelta(stack, appearingCtrl)),
426
+ perform(appearingCtrl.getStatusBarController(), null, sbc -> sbc.getStatusBarPushAnimation(appearingOptions)),
427
+ perform(bottomTabsController, null, btc -> btc.getPushAnimation(appearingOptions))
428
+ );
426
429
  }
427
430
 
428
- public List<Animator> getAdditionalPopAnimations(Options appearingOptions, Options disappearingOptions) {
431
+ public List<Animator> getAdditionalPopAnimations(Options appearingOptions, Options disappearingOptions, ViewController<?> appearingCtrl) {
429
432
  return CollectionUtils.asList(
430
433
  topBarController.getPopAnimation(appearingOptions, disappearingOptions),
431
- perform(bottomTabsController, null, btc -> btc.getPopAnimation(appearingOptions, disappearingOptions)));
434
+ perform(appearingCtrl.getStatusBarController(), null, sbc -> sbc.getStatusBarPopAnimation(appearingOptions, disappearingOptions)),
435
+ perform(bottomTabsController, null, btc -> btc.getPopAnimation(appearingOptions, disappearingOptions))
436
+ );
432
437
  }
433
438
 
434
439
  public List<Animator> getAdditionalSetRootAnimations(StackController stack, ViewController<?> appearing,
@@ -618,9 +623,7 @@ public class StackPresenter {
618
623
  if (resolveOptions.subtitle.font.hasValue()) {
619
624
  topBar.setSubtitleTypeface(typefaceLoader, resolveOptions.subtitle.font);
620
625
  }
621
-
622
- if (topBarOptions.background.color.hasValue())
623
- topBar.setBackgroundColor(topBarOptions.background.color.get());
626
+ topBarController.setBackgroundColor(topBarOptions);
624
627
 
625
628
  if (topBarOptions.background.component.hasValue()) {
626
629
  if (backgroundControllers.containsKey(component)) {
@@ -0,0 +1,9 @@
1
+ package com.reactnativenavigation.viewcontrollers.stack.statusbar
2
+
3
+ import android.animation.Animator
4
+ import com.reactnativenavigation.options.Options
5
+
6
+ interface StatusBarController {
7
+ fun getStatusBarPushAnimation(appearingOptions: Options): Animator?
8
+ fun getStatusBarPopAnimation(appearingOptions: Options, disappearingOptions: Options): Animator?
9
+ }