react-native-screens 3.32.0 → 3.33.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 (142) hide show
  1. package/README.md +17 -13
  2. package/RNScreens.podspec +10 -52
  3. package/android/CMakeLists.txt +48 -4
  4. package/android/build.gradle +9 -81
  5. package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +25 -16
  6. package/android/src/fabric/java/com/swmansion/rnscreens/NativeProxy.kt +53 -0
  7. package/android/src/main/cpp/NativeProxy.cpp +51 -0
  8. package/android/src/main/cpp/NativeProxy.h +35 -0
  9. package/android/src/main/cpp/OnLoad.cpp +8 -0
  10. package/android/src/main/java/com/swmansion/rnscreens/CustomSearchView.kt +5 -2
  11. package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +4 -1
  12. package/android/src/main/java/com/swmansion/rnscreens/FragmentBackPressOverrider.kt +2 -2
  13. package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +36 -17
  14. package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +134 -38
  15. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +52 -30
  16. package/android/src/main/java/com/swmansion/rnscreens/ScreenContainerViewManager.kt +17 -7
  17. package/android/src/main/java/com/swmansion/rnscreens/ScreenEventDispatcher.kt +10 -2
  18. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +56 -27
  19. package/android/src/main/java/com/swmansion/rnscreens/ScreenFragmentWrapper.kt +8 -1
  20. package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +50 -19
  21. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +60 -37
  22. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragmentWrapper.kt +4 -0
  23. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +85 -58
  24. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +128 -37
  25. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubview.kt +19 -4
  26. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +16 -10
  27. package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +28 -25
  28. package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +173 -78
  29. package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +59 -24
  30. package/android/src/main/java/com/swmansion/rnscreens/ScreensModule.kt +30 -8
  31. package/android/src/main/java/com/swmansion/rnscreens/ScreensShadowNode.kt +3 -1
  32. package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +101 -50
  33. package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +29 -22
  34. package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +7 -2
  35. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderAttachedEvent.kt +4 -1
  36. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderBackButtonClickedEvent.kt +4 -1
  37. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderDetachedEvent.kt +4 -1
  38. package/android/src/main/java/com/swmansion/rnscreens/events/HeaderHeightChangeEvent.kt +5 -5
  39. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenAppearEvent.kt +4 -1
  40. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDisappearEvent.kt +4 -1
  41. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenDismissedEvent.kt +8 -4
  42. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenTransitionProgressEvent.kt +7 -6
  43. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillAppearEvent.kt +4 -1
  44. package/android/src/main/java/com/swmansion/rnscreens/events/ScreenWillDisappearEvent.kt +4 -1
  45. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarBlurEvent.kt +4 -1
  46. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarChangeTextEvent.kt +4 -3
  47. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarCloseEvent.kt +4 -1
  48. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarFocusEvent.kt +4 -1
  49. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarOpenEvent.kt +4 -1
  50. package/android/src/main/java/com/swmansion/rnscreens/events/SearchBarSearchButtonPressEvent.kt +9 -4
  51. package/android/src/main/java/com/swmansion/rnscreens/events/StackFinishTransitioningEvent.kt +4 -1
  52. package/android/src/main/java/com/swmansion/rnscreens/utils/DeviceUtils.kt +1 -5
  53. package/android/src/main/java/com/swmansion/rnscreens/utils/ScreenDummyLayoutHelper.kt +214 -0
  54. package/android/src/main/jni/CMakeLists.txt +5 -4
  55. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +3 -0
  56. package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +1 -0
  57. package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +10 -5
  58. package/android/src/paper/java/com/swmansion/rnscreens/NativeProxy.kt +19 -0
  59. package/android/src/paper/java/com/swmansion/rnscreens/NativeScreensModuleSpec.java +4 -0
  60. package/common/cpp/react/renderer/components/rnscreens/FrameCorrectionModes.h +51 -0
  61. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.cpp +2 -1
  62. package/common/cpp/react/renderer/components/rnscreens/RNSModalScreenShadowNode.h +1 -1
  63. package/common/cpp/react/renderer/components/rnscreens/RNSScreenComponentDescriptor.h +140 -1
  64. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.cpp +51 -1
  65. package/common/cpp/react/renderer/components/rnscreens/RNSScreenShadowNode.h +23 -1
  66. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.cpp +20 -0
  67. package/common/cpp/react/renderer/components/rnscreens/RNSScreenState.h +23 -1
  68. package/common/cpp/react/renderer/components/rnscreens/utils/RectUtil.h +36 -0
  69. package/cpp/RNSScreenRemovalListener.cpp +25 -0
  70. package/cpp/RNSScreenRemovalListener.h +20 -0
  71. package/ios/RNSConvert.h +1 -0
  72. package/ios/RNSModalScreen.mm +22 -0
  73. package/ios/RNSModule.mm +1 -1
  74. package/ios/RNSScreen.h +2 -1
  75. package/ios/RNSScreen.mm +27 -19
  76. package/ios/RNSScreenStack.mm +24 -77
  77. package/ios/RNSScreenStackAnimator.mm +43 -6
  78. package/ios/RNSScreenStackHeaderConfig.mm +49 -11
  79. package/ios/RNSScreenStackHeaderSubview.mm +8 -0
  80. package/ios/utils/UIView+RNSUtility.h +23 -0
  81. package/ios/utils/UIView+RNSUtility.mm +55 -0
  82. package/lib/commonjs/components/ScreenStack.js +8 -1
  83. package/lib/commonjs/components/ScreenStack.js.map +1 -1
  84. package/lib/commonjs/fabric/ModalScreenNativeComponent.js.map +1 -1
  85. package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -1
  86. package/lib/commonjs/native-stack/views/NativeStackView.js +2 -0
  87. package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
  88. package/lib/module/components/ScreenStack.js +8 -1
  89. package/lib/module/components/ScreenStack.js.map +1 -1
  90. package/lib/module/fabric/ModalScreenNativeComponent.js.map +1 -1
  91. package/lib/module/fabric/ScreenNativeComponent.js.map +1 -1
  92. package/lib/module/native-stack/views/NativeStackView.js +2 -0
  93. package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
  94. package/lib/typescript/components/ScreenStack.d.ts.map +1 -1
  95. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts +1 -0
  96. package/lib/typescript/fabric/ModalScreenNativeComponent.d.ts.map +1 -1
  97. package/lib/typescript/fabric/ScreenNativeComponent.d.ts +1 -0
  98. package/lib/typescript/fabric/ScreenNativeComponent.d.ts.map +1 -1
  99. package/lib/typescript/native-stack/types.d.ts +10 -0
  100. package/lib/typescript/native-stack/types.d.ts.map +1 -1
  101. package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
  102. package/lib/typescript/types.d.ts +10 -0
  103. package/lib/typescript/types.d.ts.map +1 -1
  104. package/native-stack/README.md +110 -99
  105. package/package.json +6 -3
  106. package/react-native.config.js +17 -15
  107. package/src/TransitionProgressContext.tsx +1 -1
  108. package/src/components/Screen.tsx +4 -4
  109. package/src/components/ScreenStack.tsx +11 -1
  110. package/src/components/ScreenStackHeaderConfig.tsx +5 -5
  111. package/src/components/ScreenStackHeaderConfig.web.tsx +6 -6
  112. package/src/components/SearchBar.tsx +4 -4
  113. package/src/core.ts +1 -1
  114. package/src/fabric/ModalScreenNativeComponent.ts +1 -0
  115. package/src/fabric/ScreenNativeComponent.ts +1 -0
  116. package/src/fabric/ScreenNavigationContainerNativeComponent.ts +1 -1
  117. package/src/fabric/ScreenStackHeaderConfigNativeComponent.ts +1 -1
  118. package/src/fabric/ScreenStackHeaderSubviewNativeComponent.ts +1 -1
  119. package/src/fabric/SearchBarNativeComponent.ts +1 -1
  120. package/src/gesture-handler/ScreenGestureDetector.tsx +5 -5
  121. package/src/gesture-handler/constraints.ts +5 -5
  122. package/src/gesture-handler/fabricUtils.ts +1 -1
  123. package/src/native-stack/contexts/GHContext.tsx +1 -1
  124. package/src/native-stack/navigators/createNativeStackNavigator.tsx +3 -3
  125. package/src/native-stack/types.tsx +14 -4
  126. package/src/native-stack/utils/getDefaultHeaderHeight.tsx +1 -1
  127. package/src/native-stack/utils/getStatusBarHeight.tsx +1 -1
  128. package/src/native-stack/utils/useAnimatedHeaderHeight.tsx +1 -1
  129. package/src/native-stack/utils/useBackPressSubscription.tsx +1 -1
  130. package/src/native-stack/utils/useHeaderHeight.tsx +1 -1
  131. package/src/native-stack/views/FontProcessor.tsx +1 -1
  132. package/src/native-stack/views/HeaderConfig.tsx +1 -1
  133. package/src/native-stack/views/NativeStackView.tsx +11 -9
  134. package/src/reanimated/ReanimatedHeaderHeightContext.tsx +1 -1
  135. package/src/reanimated/ReanimatedNativeStackScreen.tsx +5 -5
  136. package/src/reanimated/ReanimatedScreen.tsx +2 -2
  137. package/src/reanimated/ReanimatedScreenProvider.tsx +1 -1
  138. package/src/reanimated/useReanimatedHeaderHeight.tsx +1 -1
  139. package/src/reanimated/useReanimatedTransitionProgress.tsx +1 -1
  140. package/src/types.tsx +15 -5
  141. package/src/useTransitionProgress.tsx +1 -1
  142. package/windows/README.md +4 -1
@@ -25,9 +25,14 @@ import com.swmansion.rnscreens.events.ScreenWillDisappearEvent
25
25
  import kotlin.math.max
26
26
  import kotlin.math.min
27
27
 
28
- open class ScreenFragment : Fragment, ScreenFragmentWrapper {
28
+ open class ScreenFragment :
29
+ Fragment,
30
+ ScreenFragmentWrapper {
29
31
  enum class ScreenLifecycleEvent {
30
- DID_APPEAR, WILL_APPEAR, DID_DISAPPEAR, WILL_DISAPPEAR
32
+ DID_APPEAR,
33
+ WILL_APPEAR,
34
+ DID_DISAPPEAR,
35
+ WILL_DISAPPEAR,
31
36
  }
32
37
 
33
38
  override val fragment: Fragment
@@ -40,6 +45,7 @@ open class ScreenFragment : Fragment, ScreenFragmentWrapper {
40
45
  override val childScreenContainers: MutableList<ScreenContainer> = ArrayList()
41
46
 
42
47
  private var shouldUpdateOnResume = false
48
+
43
49
  // if we don't set it, it will be 0.0f at the beginning so the progress will not be sent
44
50
  // due to progress value being already 0.0f
45
51
  private var transitionProgress = -1f
@@ -57,7 +63,7 @@ open class ScreenFragment : Fragment, ScreenFragmentWrapper {
57
63
 
58
64
  constructor() {
59
65
  throw IllegalStateException(
60
- "Screen fragments should never be restored. Follow instructions from https://github.com/software-mansion/react-native-screens/issues/17#issuecomment-424704067 to properly configure your main activity."
66
+ "Screen fragments should never be restored. Follow instructions from https://github.com/software-mansion/react-native-screens/issues/17#issuecomment-424704067 to properly configure your main activity.",
61
67
  )
62
68
  }
63
69
 
@@ -77,14 +83,17 @@ open class ScreenFragment : Fragment, ScreenFragmentWrapper {
77
83
  override fun onCreateView(
78
84
  inflater: LayoutInflater,
79
85
  container: ViewGroup?,
80
- savedInstanceState: Bundle?
86
+ savedInstanceState: Bundle?,
81
87
  ): View? {
82
- screen.layoutParams = FrameLayout.LayoutParams(
83
- ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
84
- )
85
- val wrapper = context?.let { ScreensFrameLayout(it) }?.apply {
86
- addView(recycleView(screen))
87
- }
88
+ screen.layoutParams =
89
+ FrameLayout.LayoutParams(
90
+ ViewGroup.LayoutParams.MATCH_PARENT,
91
+ ViewGroup.LayoutParams.MATCH_PARENT,
92
+ )
93
+ val wrapper =
94
+ context?.let { ScreensFrameLayout(it) }?.apply {
95
+ addView(recycleView(screen))
96
+ }
88
97
  return wrapper
89
98
  }
90
99
 
@@ -154,12 +163,13 @@ open class ScreenFragment : Fragment, ScreenFragmentWrapper {
154
163
  return null
155
164
  }
156
165
 
157
- override fun canDispatchLifecycleEvent(event: ScreenLifecycleEvent): Boolean = when (event) {
158
- ScreenLifecycleEvent.WILL_APPEAR -> canDispatchWillAppear
159
- ScreenLifecycleEvent.DID_APPEAR -> canDispatchAppear
160
- ScreenLifecycleEvent.WILL_DISAPPEAR -> !canDispatchWillAppear
161
- ScreenLifecycleEvent.DID_DISAPPEAR -> !canDispatchAppear
162
- }
166
+ override fun canDispatchLifecycleEvent(event: ScreenLifecycleEvent): Boolean =
167
+ when (event) {
168
+ ScreenLifecycleEvent.WILL_APPEAR -> canDispatchWillAppear
169
+ ScreenLifecycleEvent.DID_APPEAR -> canDispatchAppear
170
+ ScreenLifecycleEvent.WILL_DISAPPEAR -> !canDispatchWillAppear
171
+ ScreenLifecycleEvent.DID_DISAPPEAR -> !canDispatchAppear
172
+ }
163
173
 
164
174
  override fun updateLastEventDispatched(event: ScreenLifecycleEvent) {
165
175
  when (event) {
@@ -190,18 +200,22 @@ open class ScreenFragment : Fragment, ScreenFragmentWrapper {
190
200
  dispatchTransitionProgressEvent(1.0f, true)
191
201
  }
192
202
 
193
- override fun dispatchLifecycleEvent(event: ScreenLifecycleEvent, fragmentWrapper: ScreenFragmentWrapper) {
203
+ override fun dispatchLifecycleEvent(
204
+ event: ScreenLifecycleEvent,
205
+ fragmentWrapper: ScreenFragmentWrapper,
206
+ ) {
194
207
  val fragment = fragmentWrapper.fragment
195
208
  if (fragment is ScreenStackFragment && fragment.canDispatchLifecycleEvent(event)) {
196
209
  fragment.screen.let {
197
210
  fragmentWrapper.updateLastEventDispatched(event)
198
211
  val surfaceId = UIManagerHelper.getSurfaceId(it)
199
- val lifecycleEvent: Event<*> = when (event) {
200
- ScreenLifecycleEvent.WILL_APPEAR -> ScreenWillAppearEvent(surfaceId, it.id)
201
- ScreenLifecycleEvent.DID_APPEAR -> ScreenAppearEvent(surfaceId, it.id)
202
- ScreenLifecycleEvent.WILL_DISAPPEAR -> ScreenWillDisappearEvent(surfaceId, it.id)
203
- ScreenLifecycleEvent.DID_DISAPPEAR -> ScreenDisappearEvent(surfaceId, it.id)
204
- }
212
+ val lifecycleEvent: Event<*> =
213
+ when (event) {
214
+ ScreenLifecycleEvent.WILL_APPEAR -> ScreenWillAppearEvent(surfaceId, it.id)
215
+ ScreenLifecycleEvent.DID_APPEAR -> ScreenAppearEvent(surfaceId, it.id)
216
+ ScreenLifecycleEvent.WILL_DISAPPEAR -> ScreenWillDisappearEvent(surfaceId, it.id)
217
+ ScreenLifecycleEvent.DID_DISAPPEAR -> ScreenDisappearEvent(surfaceId, it.id)
218
+ }
205
219
  val screenContext = screen.context as ReactContext
206
220
  val eventDispatcher: EventDispatcher? =
207
221
  UIManagerHelper.getEventDispatcherForReactTag(screenContext, screen.id)
@@ -225,7 +239,10 @@ open class ScreenFragment : Fragment, ScreenFragmentWrapper {
225
239
  ?.dispatchEvent(HeaderBackButtonClickedEvent(surfaceId, screen.id))
226
240
  }
227
241
 
228
- override fun dispatchTransitionProgressEvent(alpha: Float, closing: Boolean) {
242
+ override fun dispatchTransitionProgressEvent(
243
+ alpha: Float,
244
+ closing: Boolean,
245
+ ) {
229
246
  if (this is ScreenStackFragment) {
230
247
  if (transitionProgress != alpha) {
231
248
  transitionProgress = max(0.0f, min(1.0f, alpha))
@@ -238,8 +255,12 @@ open class ScreenFragment : Fragment, ScreenFragmentWrapper {
238
255
  ?.dispatchEvent(
239
256
  ScreenTransitionProgressEvent(
240
257
  UIManagerHelper.getSurfaceId(screenContext),
241
- screen.id, transitionProgress, closing, goingForward, coalescingKey
242
- )
258
+ screen.id,
259
+ transitionProgress,
260
+ closing,
261
+ goingForward,
262
+ coalescingKey,
263
+ ),
243
264
  )
244
265
  }
245
266
  }
@@ -328,7 +349,15 @@ open class ScreenFragment : Fragment, ScreenFragmentWrapper {
328
349
  - progress is 1 -> key 2
329
350
  - progress is between 0 and 1 -> key 3
330
351
  */
331
- return (if (progress == 0.0f) 1 else if (progress == 1.0f) 2 else 3).toShort()
352
+ return (
353
+ if (progress == 0.0f) {
354
+ 1
355
+ } else if (progress == 1.0f) {
356
+ 2
357
+ } else {
358
+ 3
359
+ }
360
+ ).toShort()
332
361
  }
333
362
  }
334
363
  }
@@ -3,20 +3,27 @@ package com.swmansion.rnscreens
3
3
  import android.app.Activity
4
4
  import com.facebook.react.bridge.ReactContext
5
5
 
6
- interface ScreenFragmentWrapper : FragmentHolder, ScreenEventDispatcher {
6
+ interface ScreenFragmentWrapper :
7
+ FragmentHolder,
8
+ ScreenEventDispatcher {
7
9
  var screen: Screen
8
10
 
9
11
  // Communication with container
10
12
  val childScreenContainers: List<ScreenContainer>
13
+
11
14
  fun addChildScreenContainer(container: ScreenContainer)
15
+
12
16
  fun removeChildScreenContainer(container: ScreenContainer)
17
+
13
18
  fun onContainerUpdate()
14
19
 
15
20
  // Animation phase callbacks
16
21
  fun onViewAnimationStart()
22
+
17
23
  fun onViewAnimationEnd()
18
24
 
19
25
  // Helpers
20
26
  fun tryGetActivity(): Activity?
27
+
21
28
  fun tryGetContext(): ReactContext?
22
29
  }
@@ -12,7 +12,9 @@ import java.util.Collections
12
12
  import kotlin.collections.ArrayList
13
13
  import kotlin.collections.HashSet
14
14
 
15
- class ScreenStack(context: Context?) : ScreenContainer(context) {
15
+ class ScreenStack(
16
+ context: Context?,
17
+ ) : ScreenContainer(context) {
16
18
  private val stack = ArrayList<ScreenStackFragmentWrapper>()
17
19
  private val dismissedWrappers: MutableSet<ScreenStackFragmentWrapper> = HashSet()
18
20
  private val drawingOpPool: MutableList<DrawingOp> = ArrayList()
@@ -142,11 +144,21 @@ class ScreenStack(context: Context?) : ScreenContainer(context) {
142
144
  StackAnimation.DEFAULT -> it.setCustomAnimations(R.anim.rns_default_enter_in, R.anim.rns_default_enter_out)
143
145
  StackAnimation.NONE -> it.setCustomAnimations(R.anim.rns_no_animation_20, R.anim.rns_no_animation_20)
144
146
  StackAnimation.FADE -> it.setCustomAnimations(R.anim.rns_fade_in, R.anim.rns_fade_out)
145
- StackAnimation.SLIDE_FROM_RIGHT -> it.setCustomAnimations(R.anim.rns_slide_in_from_right, R.anim.rns_slide_out_to_left)
146
- StackAnimation.SLIDE_FROM_LEFT -> it.setCustomAnimations(R.anim.rns_slide_in_from_left, R.anim.rns_slide_out_to_right)
147
- StackAnimation.SLIDE_FROM_BOTTOM -> it.setCustomAnimations(
148
- R.anim.rns_slide_in_from_bottom, R.anim.rns_no_animation_medium
149
- )
147
+ StackAnimation.SLIDE_FROM_RIGHT ->
148
+ it.setCustomAnimations(
149
+ R.anim.rns_slide_in_from_right,
150
+ R.anim.rns_slide_out_to_left,
151
+ )
152
+ StackAnimation.SLIDE_FROM_LEFT ->
153
+ it.setCustomAnimations(
154
+ R.anim.rns_slide_in_from_left,
155
+ R.anim.rns_slide_out_to_right,
156
+ )
157
+ StackAnimation.SLIDE_FROM_BOTTOM ->
158
+ it.setCustomAnimations(
159
+ R.anim.rns_slide_in_from_bottom,
160
+ R.anim.rns_no_animation_medium,
161
+ )
150
162
  StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_fade_from_bottom, R.anim.rns_no_animation_350)
151
163
  StackAnimation.IOS -> it.setCustomAnimations(R.anim.rns_slide_in_from_right_ios, R.anim.rns_slide_out_to_left_ios)
152
164
  }
@@ -155,11 +167,21 @@ class ScreenStack(context: Context?) : ScreenContainer(context) {
155
167
  StackAnimation.DEFAULT -> it.setCustomAnimations(R.anim.rns_default_exit_in, R.anim.rns_default_exit_out)
156
168
  StackAnimation.NONE -> it.setCustomAnimations(R.anim.rns_no_animation_20, R.anim.rns_no_animation_20)
157
169
  StackAnimation.FADE -> it.setCustomAnimations(R.anim.rns_fade_in, R.anim.rns_fade_out)
158
- StackAnimation.SLIDE_FROM_RIGHT -> it.setCustomAnimations(R.anim.rns_slide_in_from_left, R.anim.rns_slide_out_to_right)
159
- StackAnimation.SLIDE_FROM_LEFT -> it.setCustomAnimations(R.anim.rns_slide_in_from_right, R.anim.rns_slide_out_to_left)
160
- StackAnimation.SLIDE_FROM_BOTTOM -> it.setCustomAnimations(
161
- R.anim.rns_no_animation_medium, R.anim.rns_slide_out_to_bottom
162
- )
170
+ StackAnimation.SLIDE_FROM_RIGHT ->
171
+ it.setCustomAnimations(
172
+ R.anim.rns_slide_in_from_left,
173
+ R.anim.rns_slide_out_to_right,
174
+ )
175
+ StackAnimation.SLIDE_FROM_LEFT ->
176
+ it.setCustomAnimations(
177
+ R.anim.rns_slide_in_from_right,
178
+ R.anim.rns_slide_out_to_left,
179
+ )
180
+ StackAnimation.SLIDE_FROM_BOTTOM ->
181
+ it.setCustomAnimations(
182
+ R.anim.rns_no_animation_medium,
183
+ R.anim.rns_slide_out_to_bottom,
184
+ )
163
185
  StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_no_animation_250, R.anim.rns_fade_to_bottom)
164
186
  StackAnimation.IOS -> it.setCustomAnimations(R.anim.rns_slide_in_from_left_ios, R.anim.rns_slide_out_to_right_ios)
165
187
  }
@@ -170,7 +192,8 @@ class ScreenStack(context: Context?) : ScreenContainer(context) {
170
192
  goingForward = shouldUseOpenAnimation
171
193
 
172
194
  if (shouldUseOpenAnimation &&
173
- newTop != null && needsDrawReordering(newTop) &&
195
+ newTop != null &&
196
+ needsDrawReordering(newTop) &&
174
197
  visibleBottom == null
175
198
  ) {
176
199
  // When using an open animation in which two screens overlap (eg. fade_from_bottom or
@@ -208,9 +231,12 @@ class ScreenStack(context: Context?) : ScreenContainer(context) {
208
231
  for (fragmentWrapper in screenWrappers) {
209
232
  // ignore all screens beneath the visible bottom
210
233
  if (beneathVisibleBottom) {
211
- beneathVisibleBottom = if (fragmentWrapper === visibleBottom) {
212
- false
213
- } else continue
234
+ beneathVisibleBottom =
235
+ if (fragmentWrapper === visibleBottom) {
236
+ false
237
+ } else {
238
+ continue
239
+ }
214
240
  }
215
241
  // when first visible screen found, make all screens after that visible
216
242
  it.add(id, fragmentWrapper.fragment).runOnCommit { top?.screen?.bringToFront() }
@@ -298,13 +324,17 @@ class ScreenStack(context: Context?) : ScreenContainer(context) {
298
324
  drawAndRelease()
299
325
  }
300
326
 
301
- override fun drawChild(canvas: Canvas, child: View, drawingTime: Long): Boolean {
327
+ override fun drawChild(
328
+ canvas: Canvas,
329
+ child: View,
330
+ drawingTime: Long,
331
+ ): Boolean {
302
332
  drawingOps.add(
303
333
  obtainDrawingOp().apply {
304
334
  this.canvas = canvas
305
335
  this.child = child
306
336
  this.drawingTime = drawingTime
307
- }
337
+ },
308
338
  )
309
339
  return true
310
340
  }
@@ -315,8 +345,9 @@ class ScreenStack(context: Context?) : ScreenContainer(context) {
315
345
  super.drawChild(op.canvas!!, op.child, op.drawingTime)
316
346
  }
317
347
 
318
- private fun obtainDrawingOp(): DrawingOp =
319
- if (drawingOpPool.isEmpty()) DrawingOp() else drawingOpPool.removeLast()
348
+ // Can't use `drawingOpPool.removeLast` here due to issues with static name resolution in Android SDK 35+.
349
+ // See: https://developer.android.com/about/versions/15/behavior-changes-15?hl=en#openjdk-api-changes
350
+ private fun obtainDrawingOp(): DrawingOp = if (drawingOpPool.isEmpty()) DrawingOp() else drawingOpPool.removeAt(drawingOpPool.lastIndex)
320
351
 
321
352
  private inner class DrawingOp {
322
353
  var canvas: Canvas? = null
@@ -21,7 +21,9 @@ import com.google.android.material.appbar.AppBarLayout
21
21
  import com.google.android.material.appbar.AppBarLayout.ScrollingViewBehavior
22
22
  import com.swmansion.rnscreens.utils.DeviceUtils
23
23
 
24
- class ScreenStackFragment : ScreenFragment, ScreenStackFragmentWrapper {
24
+ class ScreenStackFragment :
25
+ ScreenFragment,
26
+ ScreenStackFragmentWrapper {
25
27
  private var appBarLayout: AppBarLayout? = null
26
28
  private var toolbar: Toolbar? = null
27
29
  private var isToolbarShadowHidden = false
@@ -37,7 +39,7 @@ class ScreenStackFragment : ScreenFragment, ScreenStackFragmentWrapper {
37
39
 
38
40
  constructor() {
39
41
  throw IllegalStateException(
40
- "ScreenStack fragments should never be restored. Follow instructions from https://github.com/software-mansion/react-native-screens/issues/17#issuecomment-424704067 to properly configure your main activity."
42
+ "ScreenStack fragments should never be restored. Follow instructions from https://github.com/software-mansion/react-native-screens/issues/17#issuecomment-424704067 to properly configure your main activity.",
41
43
  )
42
44
  }
43
45
 
@@ -54,9 +56,12 @@ class ScreenStackFragment : ScreenFragment, ScreenStackFragmentWrapper {
54
56
 
55
57
  override fun setToolbar(toolbar: Toolbar) {
56
58
  appBarLayout?.addView(toolbar)
57
- toolbar.layoutParams = AppBarLayout.LayoutParams(
58
- AppBarLayout.LayoutParams.MATCH_PARENT, AppBarLayout.LayoutParams.WRAP_CONTENT
59
- ).apply { scrollFlags = 0 }
59
+ toolbar.layoutParams =
60
+ AppBarLayout
61
+ .LayoutParams(
62
+ AppBarLayout.LayoutParams.MATCH_PARENT,
63
+ AppBarLayout.LayoutParams.WRAP_CONTENT,
64
+ ).apply { scrollFlags = 0 }
60
65
  this.toolbar = toolbar
61
66
  }
62
67
 
@@ -102,31 +107,38 @@ class ScreenStackFragment : ScreenFragment, ScreenStackFragmentWrapper {
102
107
  override fun onCreateView(
103
108
  inflater: LayoutInflater,
104
109
  container: ViewGroup?,
105
- savedInstanceState: Bundle?
110
+ savedInstanceState: Bundle?,
106
111
  ): View? {
107
112
  val view: ScreensCoordinatorLayout? =
108
113
  context?.let { ScreensCoordinatorLayout(it, this) }
109
114
 
110
- screen.layoutParams = CoordinatorLayout.LayoutParams(
111
- LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT
112
- ).apply { behavior = if (isToolbarTranslucent) null else ScrollingViewBehavior() }
115
+ screen.layoutParams =
116
+ CoordinatorLayout
117
+ .LayoutParams(
118
+ LinearLayout.LayoutParams.MATCH_PARENT,
119
+ LinearLayout.LayoutParams.MATCH_PARENT,
120
+ ).apply { behavior = if (isToolbarTranslucent) null else ScrollingViewBehavior() }
113
121
 
114
122
  view?.addView(recycleView(screen))
115
123
 
116
- appBarLayout = context?.let { AppBarLayout(it) }?.apply {
117
- // By default AppBarLayout will have a background color set but since we cover the whole layout
118
- // with toolbar (that can be semi-transparent) the bar layout background color does not pay a
119
- // role. On top of that it breaks screens animations when alfa offscreen compositing is off
120
- // (which is the default)
121
- setBackgroundColor(Color.TRANSPARENT)
122
- layoutParams = AppBarLayout.LayoutParams(
123
- AppBarLayout.LayoutParams.MATCH_PARENT, AppBarLayout.LayoutParams.WRAP_CONTENT
124
- )
125
- }
124
+ appBarLayout =
125
+ context?.let { AppBarLayout(it) }?.apply {
126
+ // By default AppBarLayout will have a background color set but since we cover the whole layout
127
+ // with toolbar (that can be semi-transparent) the bar layout background color does not pay a
128
+ // role. On top of that it breaks screens animations when alfa offscreen compositing is off
129
+ // (which is the default)
130
+ setBackgroundColor(Color.TRANSPARENT)
131
+ layoutParams =
132
+ AppBarLayout.LayoutParams(
133
+ AppBarLayout.LayoutParams.MATCH_PARENT,
134
+ AppBarLayout.LayoutParams.WRAP_CONTENT,
135
+ )
136
+ }
126
137
 
127
138
  view?.addView(appBarLayout)
128
139
  if (isToolbarShadowHidden) {
129
140
  appBarLayout?.elevation = 0f
141
+ appBarLayout?.stateListAnimator = null
130
142
  }
131
143
  toolbar?.let { appBarLayout?.addView(recycleView(it)) }
132
144
  setHasOptionsMenu(true)
@@ -134,8 +146,9 @@ class ScreenStackFragment : ScreenFragment, ScreenStackFragmentWrapper {
134
146
  }
135
147
 
136
148
  override fun onStop() {
137
- if (DeviceUtils.isPlatformAndroidTV(context))
149
+ if (DeviceUtils.isPlatformAndroidTV(context)) {
138
150
  lastFocusedChild = findLastFocusedChild()
151
+ }
139
152
 
140
153
  super.onStop()
141
154
  }
@@ -145,7 +158,10 @@ class ScreenStackFragment : ScreenFragment, ScreenStackFragmentWrapper {
145
158
  return super.onPrepareOptionsMenu(menu)
146
159
  }
147
160
 
148
- override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
161
+ override fun onCreateOptionsMenu(
162
+ menu: Menu,
163
+ inflater: MenuInflater,
164
+ ) {
149
165
  updateToolbarMenu(menu)
150
166
  return super.onCreateOptionsMenu(menu, inflater)
151
167
  }
@@ -215,7 +231,7 @@ class ScreenStackFragment : ScreenFragment, ScreenStackFragmentWrapper {
215
231
 
216
232
  private class ScreensCoordinatorLayout(
217
233
  context: Context,
218
- private val mFragment: ScreenFragment
234
+ private val mFragment: ScreenFragment,
219
235
  ) : CoordinatorLayout(context) {
220
236
  private val mAnimationListener: Animation.AnimationListener =
221
237
  object : Animation.AnimationListener {
@@ -243,20 +259,22 @@ class ScreenStackFragment : ScreenFragment, ScreenStackFragmentWrapper {
243
259
  val fakeAnimation = ScreensAnimation(mFragment).apply { duration = animation.duration }
244
260
 
245
261
  if (animation is AnimationSet && !mFragment.isRemoving) {
246
- animation.apply {
247
- addAnimation(fakeAnimation)
248
- setAnimationListener(mAnimationListener)
249
- }.also {
250
- super.startAnimation(it)
251
- }
262
+ animation
263
+ .apply {
264
+ addAnimation(fakeAnimation)
265
+ setAnimationListener(mAnimationListener)
266
+ }.also {
267
+ super.startAnimation(it)
268
+ }
252
269
  } else {
253
- AnimationSet(true).apply {
254
- addAnimation(animation)
255
- addAnimation(fakeAnimation)
256
- setAnimationListener(mAnimationListener)
257
- }.also {
258
- super.startAnimation(it)
259
- }
270
+ AnimationSet(true)
271
+ .apply {
272
+ addAnimation(animation)
273
+ addAnimation(fakeAnimation)
274
+ setAnimationListener(mAnimationListener)
275
+ }.also {
276
+ super.startAnimation(it)
277
+ }
260
278
  }
261
279
  }
262
280
 
@@ -274,8 +292,13 @@ class ScreenStackFragment : ScreenFragment, ScreenStackFragmentWrapper {
274
292
  }
275
293
  }
276
294
 
277
- private class ScreensAnimation(private val mFragment: ScreenFragment) : Animation() {
278
- override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
295
+ private class ScreensAnimation(
296
+ private val mFragment: ScreenFragment,
297
+ ) : Animation() {
298
+ override fun applyTransformation(
299
+ interpolatedTime: Float,
300
+ t: Transformation,
301
+ ) {
279
302
  super.applyTransformation(interpolatedTime, t)
280
303
  // interpolated time should be the progress of the current transition
281
304
  mFragment.dispatchTransitionProgressEvent(interpolatedTime, !mFragment.isResumed)
@@ -5,11 +5,15 @@ import androidx.appcompat.widget.Toolbar
5
5
  interface ScreenStackFragmentWrapper : ScreenFragmentWrapper {
6
6
  // Toolbar management
7
7
  fun removeToolbar()
8
+
8
9
  fun setToolbar(toolbar: Toolbar)
10
+
9
11
  fun setToolbarShadowHidden(hidden: Boolean)
12
+
10
13
  fun setToolbarTranslucent(translucent: Boolean)
11
14
 
12
15
  // Navigation
13
16
  fun canNavigateBack(): Boolean
17
+
14
18
  fun dismiss()
15
19
  }