react-native-screens 4.10.0-beta.1 → 4.10.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt +3 -8
- package/android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt +111 -15
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +11 -2
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +174 -199
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +31 -285
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +89 -54
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigShadowNode.kt +3 -0
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/bottomsheet/SheetDelegate.kt +257 -3
- package/android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/utils/FragmentTransactionKt.kt +103 -0
- package/android/src/main/java/com/swmansion/rnscreens/utils/InsetsKt.kt +31 -0
- package/android/src/main/java/com/swmansion/rnscreens/utils/PaddingBundle.kt +1 -0
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledHeaderConfigViewGroup.kt +14 -5
- package/ios/RNSFullWindowOverlay.mm +6 -6
- package/lib/commonjs/components/Screen.js +5 -3
- package/lib/commonjs/components/Screen.js.map +1 -1
- package/lib/commonjs/native-stack/views/NativeStackView.js +3 -5
- package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/module/components/Screen.js +5 -3
- package/lib/module/components/Screen.js.map +1 -1
- package/lib/module/native-stack/views/NativeStackView.js +3 -5
- package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/typescript/components/Screen.d.ts.map +1 -1
- package/lib/typescript/native-stack/views/NativeStackView.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Screen.tsx +7 -5
- package/src/native-stack/views/NativeStackView.tsx +11 -12
- package/android/src/main/java/com/swmansion/rnscreens/NativeDismissalObserver.kt +0 -12
|
@@ -9,8 +9,75 @@ import com.facebook.react.uimanager.UIManagerHelper
|
|
|
9
9
|
import com.swmansion.rnscreens.Screen.StackAnimation
|
|
10
10
|
import com.swmansion.rnscreens.bottomsheet.isSheetFitToContents
|
|
11
11
|
import com.swmansion.rnscreens.events.StackFinishTransitioningEvent
|
|
12
|
+
import com.swmansion.rnscreens.utils.setTweenAnimations
|
|
12
13
|
import java.util.Collections
|
|
13
14
|
import kotlin.collections.ArrayList
|
|
15
|
+
import kotlin.math.max
|
|
16
|
+
|
|
17
|
+
internal interface ChildDrawingOrderStrategy {
|
|
18
|
+
/**
|
|
19
|
+
* Mutates the list of draw operations **in-place**.
|
|
20
|
+
*/
|
|
21
|
+
fun apply(drawingOperations: MutableList<ScreenStack.DrawingOp>)
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Enables the given strategy. When enabled - the strategy **might** mutate the operations
|
|
25
|
+
* list passed to `apply` method.
|
|
26
|
+
*/
|
|
27
|
+
fun enable()
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Disables the given strategy - even when `apply` is called it **must not** produce
|
|
31
|
+
* any side effect (it must not manipulate the drawing operations list passed to `apply` method).
|
|
32
|
+
*/
|
|
33
|
+
fun disable()
|
|
34
|
+
|
|
35
|
+
fun isEnabled(): Boolean
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
internal abstract class ChildDrawingOrderStrategyBase(
|
|
39
|
+
var enabled: Boolean = false,
|
|
40
|
+
) : ChildDrawingOrderStrategy {
|
|
41
|
+
override fun enable() {
|
|
42
|
+
enabled = true
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
override fun disable() {
|
|
46
|
+
enabled = false
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
override fun isEnabled() = enabled
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
internal class SwapLastTwo : ChildDrawingOrderStrategyBase() {
|
|
53
|
+
override fun apply(drawingOperations: MutableList<ScreenStack.DrawingOp>) {
|
|
54
|
+
if (!isEnabled()) {
|
|
55
|
+
return
|
|
56
|
+
}
|
|
57
|
+
if (drawingOperations.size >= 2) {
|
|
58
|
+
Collections.swap(drawingOperations, drawingOperations.lastIndex, drawingOperations.lastIndex - 1)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
internal class ReverseOrderInRange(
|
|
64
|
+
val range: IntRange,
|
|
65
|
+
) : ChildDrawingOrderStrategyBase() {
|
|
66
|
+
override fun apply(drawingOperations: MutableList<ScreenStack.DrawingOp>) {
|
|
67
|
+
if (!isEnabled()) {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
var startRange = range.start
|
|
72
|
+
var endRange = range.endInclusive
|
|
73
|
+
|
|
74
|
+
while (startRange < endRange) {
|
|
75
|
+
Collections.swap(drawingOperations, startRange, endRange)
|
|
76
|
+
startRange += 1
|
|
77
|
+
endRange -= 1
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
14
81
|
|
|
15
82
|
class ScreenStack(
|
|
16
83
|
context: Context?,
|
|
@@ -21,9 +88,10 @@ class ScreenStack(
|
|
|
21
88
|
private var drawingOps: MutableList<DrawingOp> = ArrayList()
|
|
22
89
|
private var topScreenWrapper: ScreenStackFragmentWrapper? = null
|
|
23
90
|
private var removalTransitionStarted = false
|
|
24
|
-
private var isDetachingCurrentScreen = false
|
|
25
|
-
private var reverseLastTwoChildren = false
|
|
26
91
|
private var previousChildrenCount = 0
|
|
92
|
+
|
|
93
|
+
private var childDrawingOrderStrategy: ChildDrawingOrderStrategy? = null
|
|
94
|
+
|
|
27
95
|
var goingForward = false
|
|
28
96
|
|
|
29
97
|
/**
|
|
@@ -55,11 +123,13 @@ class ScreenStack(
|
|
|
55
123
|
|
|
56
124
|
override fun startViewTransition(view: View) {
|
|
57
125
|
super.startViewTransition(view)
|
|
126
|
+
childDrawingOrderStrategy?.enable()
|
|
58
127
|
removalTransitionStarted = true
|
|
59
128
|
}
|
|
60
129
|
|
|
61
130
|
override fun endViewTransition(view: View) {
|
|
62
131
|
super.endViewTransition(view)
|
|
132
|
+
childDrawingOrderStrategy?.disable()
|
|
63
133
|
if (removalTransitionStarted) {
|
|
64
134
|
removalTransitionStarted = false
|
|
65
135
|
dispatchOnFinishTransitioning()
|
|
@@ -97,208 +167,131 @@ class ScreenStack(
|
|
|
97
167
|
// when all screens are dismissed and no screen is to be displayed on top. We need to gracefully
|
|
98
168
|
// handle the case of newTop being NULL, which happens in several places below
|
|
99
169
|
var newTop: ScreenFragmentWrapper? = null // newTop is nullable, see the above comment ^
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
170
|
+
|
|
171
|
+
// this is only set if newTop has one of transparent presentation modes
|
|
172
|
+
var visibleBottom: ScreenFragmentWrapper? = null
|
|
173
|
+
|
|
174
|
+
// reset, to not use previously set strategy by mistake
|
|
175
|
+
childDrawingOrderStrategy = null
|
|
176
|
+
|
|
177
|
+
// Determine new first & last visible screens.
|
|
178
|
+
// Scope function to limit the scope of locals.
|
|
179
|
+
run {
|
|
180
|
+
val notDismissedWrappers =
|
|
181
|
+
screenWrappers
|
|
182
|
+
.asReversed()
|
|
183
|
+
.asSequence()
|
|
184
|
+
.filter { !dismissedWrappers.contains(it) && it.screen.activityState !== Screen.ActivityState.INACTIVE }
|
|
185
|
+
|
|
186
|
+
newTop = notDismissedWrappers.firstOrNull()
|
|
187
|
+
visibleBottom =
|
|
188
|
+
notDismissedWrappers
|
|
189
|
+
.dropWhile { it.screen.isTransparent() }
|
|
190
|
+
.firstOrNull()
|
|
191
|
+
?.takeUnless { it === newTop }
|
|
116
192
|
}
|
|
117
193
|
|
|
118
194
|
var shouldUseOpenAnimation = true
|
|
119
195
|
var stackAnimation: StackAnimation? = null
|
|
120
|
-
|
|
196
|
+
|
|
197
|
+
val newTopAlreadyInStack = stack.contains(newTop)
|
|
198
|
+
val topScreenWillChange = newTop !== topScreenWrapper
|
|
199
|
+
|
|
200
|
+
if (newTop != null && !newTopAlreadyInStack) {
|
|
121
201
|
// if new top screen wasn't on stack we do "open animation" so long it is not the very first
|
|
122
202
|
// screen on stack
|
|
123
|
-
if (topScreenWrapper != null
|
|
203
|
+
if (topScreenWrapper != null) {
|
|
124
204
|
// there was some other screen attached before
|
|
125
205
|
// if the previous top screen does not exist anymore and the new top was not on the stack
|
|
126
206
|
// before, probably replace or reset was called, so we play the "close animation".
|
|
127
207
|
// Otherwise it's open animation
|
|
128
|
-
val
|
|
208
|
+
val previousTopScreenRemainsInStack = topScreenWrapper?.let { screenWrappers.contains(it) } == true
|
|
129
209
|
val isPushReplace = newTop.screen.replaceAnimation === Screen.ReplaceAnimation.PUSH
|
|
130
|
-
shouldUseOpenAnimation =
|
|
210
|
+
shouldUseOpenAnimation = previousTopScreenRemainsInStack || isPushReplace
|
|
131
211
|
// if the replace animation is `push`, the new top screen provides the animation, otherwise the previous one
|
|
132
212
|
stackAnimation = if (shouldUseOpenAnimation) newTop.screen.stackAnimation else topScreenWrapper?.screen?.stackAnimation
|
|
133
|
-
} else
|
|
213
|
+
} else {
|
|
134
214
|
// mTopScreen was not present before so newTop is the first screen added to a stack
|
|
135
215
|
// and we don't want the animation when it is entering
|
|
136
216
|
stackAnimation = StackAnimation.NONE
|
|
137
217
|
goingForward = true
|
|
138
218
|
}
|
|
139
|
-
} else if (
|
|
219
|
+
} else if (newTop != null && topScreenWrapper != null && topScreenWillChange) {
|
|
140
220
|
// otherwise if we are performing top screen change we do "close animation"
|
|
141
221
|
shouldUseOpenAnimation = false
|
|
142
222
|
stackAnimation = topScreenWrapper?.screen?.stackAnimation
|
|
143
223
|
}
|
|
144
224
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
R.anim.rns_no_animation_medium,
|
|
182
|
-
)
|
|
183
|
-
StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_fade_from_bottom, R.anim.rns_no_animation_350)
|
|
184
|
-
StackAnimation.IOS_FROM_RIGHT ->
|
|
185
|
-
it.setCustomAnimations(
|
|
186
|
-
R.anim.rns_ios_from_right_foreground_open,
|
|
187
|
-
R.anim.rns_ios_from_right_background_open,
|
|
188
|
-
)
|
|
189
|
-
StackAnimation.IOS_FROM_LEFT ->
|
|
190
|
-
it.setCustomAnimations(
|
|
191
|
-
R.anim.rns_ios_from_left_foreground_open,
|
|
192
|
-
R.anim.rns_ios_from_left_background_open,
|
|
193
|
-
)
|
|
194
|
-
}
|
|
195
|
-
} else {
|
|
196
|
-
when (stackAnimation) {
|
|
197
|
-
StackAnimation.DEFAULT ->
|
|
198
|
-
it.setCustomAnimations(
|
|
199
|
-
R.anim.rns_default_exit_in,
|
|
200
|
-
R.anim.rns_default_exit_out,
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
StackAnimation.NONE ->
|
|
204
|
-
it.setCustomAnimations(
|
|
205
|
-
R.anim.rns_no_animation_20,
|
|
206
|
-
R.anim.rns_no_animation_20,
|
|
207
|
-
)
|
|
208
|
-
|
|
209
|
-
StackAnimation.FADE ->
|
|
210
|
-
it.setCustomAnimations(
|
|
211
|
-
R.anim.rns_fade_in,
|
|
212
|
-
R.anim.rns_fade_out,
|
|
213
|
-
)
|
|
214
|
-
|
|
215
|
-
StackAnimation.SLIDE_FROM_RIGHT ->
|
|
216
|
-
it.setCustomAnimations(
|
|
217
|
-
R.anim.rns_slide_in_from_left,
|
|
218
|
-
R.anim.rns_slide_out_to_right,
|
|
219
|
-
)
|
|
220
|
-
StackAnimation.SLIDE_FROM_LEFT ->
|
|
221
|
-
it.setCustomAnimations(
|
|
222
|
-
R.anim.rns_slide_in_from_right,
|
|
223
|
-
R.anim.rns_slide_out_to_left,
|
|
224
|
-
)
|
|
225
|
-
StackAnimation.SLIDE_FROM_BOTTOM ->
|
|
226
|
-
it.setCustomAnimations(
|
|
227
|
-
R.anim.rns_no_animation_medium,
|
|
228
|
-
R.anim.rns_slide_out_to_bottom,
|
|
229
|
-
)
|
|
230
|
-
StackAnimation.FADE_FROM_BOTTOM -> it.setCustomAnimations(R.anim.rns_no_animation_250, R.anim.rns_fade_to_bottom)
|
|
231
|
-
StackAnimation.IOS_FROM_RIGHT ->
|
|
232
|
-
it.setCustomAnimations(
|
|
233
|
-
R.anim.rns_ios_from_right_background_close,
|
|
234
|
-
R.anim.rns_ios_from_right_foreground_close,
|
|
235
|
-
)
|
|
236
|
-
StackAnimation.IOS_FROM_LEFT ->
|
|
237
|
-
it.setCustomAnimations(
|
|
238
|
-
R.anim.rns_ios_from_left_background_close,
|
|
239
|
-
R.anim.rns_ios_from_left_foreground_close,
|
|
240
|
-
)
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
// animation logic end
|
|
245
|
-
goingForward = shouldUseOpenAnimation
|
|
246
|
-
|
|
247
|
-
if (shouldUseOpenAnimation &&
|
|
248
|
-
newTop != null &&
|
|
249
|
-
needsDrawReordering(newTop, stackAnimation) &&
|
|
250
|
-
visibleBottom == null
|
|
251
|
-
) {
|
|
252
|
-
// When using an open animation in which two screens overlap (eg. fade_from_bottom or
|
|
253
|
-
// slide_from_bottom), we want to draw the previous screen under the new one,
|
|
254
|
-
// which is apparently not the default option. Android always draws the disappearing view
|
|
255
|
-
// on top of the appearing one. We then reverse the order of the views so the new screen
|
|
256
|
-
// appears on top of the previous one. You can read more about in the comment
|
|
257
|
-
// for the code we use to change that behavior:
|
|
258
|
-
// https://github.com/airbnb/native-navigation/blob/9cf50bf9b751b40778f473f3b19fcfe2c4d40599/lib/android/src/main/java/com/airbnb/android/react/navigation/ScreenCoordinatorLayout.java#L18
|
|
259
|
-
// Note: This should not be set in case there is only a single screen in stack or animation `none` is used. Atm needsDrawReordering implementation guards that assuming that first screen on stack uses `NONE` animation.
|
|
260
|
-
isDetachingCurrentScreen = true
|
|
225
|
+
goingForward = shouldUseOpenAnimation
|
|
226
|
+
|
|
227
|
+
if (shouldUseOpenAnimation &&
|
|
228
|
+
newTop != null &&
|
|
229
|
+
needsDrawReordering(newTop, stackAnimation) &&
|
|
230
|
+
visibleBottom == null
|
|
231
|
+
) {
|
|
232
|
+
// When using an open animation in which two screens overlap (eg. fade_from_bottom or
|
|
233
|
+
// slide_from_bottom), we want to draw the previous screen under the new one,
|
|
234
|
+
// which is apparently not the default option. Android always draws the disappearing view
|
|
235
|
+
// on top of the appearing one. We then reverse the order of the views so the new screen
|
|
236
|
+
// appears on top of the previous one. You can read more about in the comment
|
|
237
|
+
// for the code we use to change that behavior:
|
|
238
|
+
// https://github.com/airbnb/native-navigation/blob/9cf50bf9b751b40778f473f3b19fcfe2c4d40599/lib/android/src/main/java/com/airbnb/android/react/navigation/ScreenCoordinatorLayout.java#L18
|
|
239
|
+
// Note: This should not be set in case there is only a single screen in stack or animation `none` is used.
|
|
240
|
+
// Atm needsDrawReordering implementation guards that assuming that first screen on stack uses `NONE` animation.
|
|
241
|
+
childDrawingOrderStrategy = SwapLastTwo()
|
|
242
|
+
} else if (newTop != null &&
|
|
243
|
+
newTopAlreadyInStack &&
|
|
244
|
+
topScreenWrapper?.screen?.isTransparent() == true &&
|
|
245
|
+
newTop.screen.isTransparent() == false
|
|
246
|
+
) {
|
|
247
|
+
// In case where we dismiss multiple transparent views we want to ensure
|
|
248
|
+
// that they are drawn in correct order - Android swaps them by default,
|
|
249
|
+
// so we need to swap the swap to unswap :D
|
|
250
|
+
val dismissedTransparentScreenApproxCount =
|
|
251
|
+
stack
|
|
252
|
+
.asReversed()
|
|
253
|
+
.asSequence()
|
|
254
|
+
.takeWhile {
|
|
255
|
+
it !== newTop &&
|
|
256
|
+
it.screen.isTransparent()
|
|
257
|
+
}.count()
|
|
258
|
+
if (dismissedTransparentScreenApproxCount > 1) {
|
|
259
|
+
childDrawingOrderStrategy =
|
|
260
|
+
ReverseOrderInRange(max(stack.lastIndex - dismissedTransparentScreenApproxCount + 1, 0)..stack.lastIndex)
|
|
261
261
|
}
|
|
262
|
+
}
|
|
262
263
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
it.remove(fragmentWrapper.fragment)
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
for (fragmentWrapper in screenWrappers) {
|
|
270
|
-
// Stop detaching screens when reaching visible bottom. All screens above bottom should be
|
|
271
|
-
// visible.
|
|
272
|
-
if (fragmentWrapper === visibleBottom) {
|
|
273
|
-
break
|
|
274
|
-
}
|
|
275
|
-
// detach all screens that should not be visible
|
|
276
|
-
if ((fragmentWrapper !== newTop && !dismissedWrappers.contains(fragmentWrapper)) ||
|
|
277
|
-
fragmentWrapper.screen.activityState === Screen.ActivityState.INACTIVE
|
|
278
|
-
) {
|
|
279
|
-
it.remove(fragmentWrapper.fragment)
|
|
280
|
-
}
|
|
264
|
+
createTransaction().let { transaction ->
|
|
265
|
+
if (stackAnimation != null) {
|
|
266
|
+
transaction.setTweenAnimations(stackAnimation, shouldUseOpenAnimation)
|
|
281
267
|
}
|
|
282
268
|
|
|
269
|
+
// Remove all screens that are currently on stack, but should be dismissed, because they're
|
|
270
|
+
// no longer rendered or were dismissed natively.
|
|
271
|
+
stack
|
|
272
|
+
.asSequence()
|
|
273
|
+
.filter { wrapper -> !screenWrappers.contains(wrapper) || dismissedWrappers.contains(wrapper) }
|
|
274
|
+
.forEach { wrapper -> transaction.remove(wrapper.fragment) }
|
|
275
|
+
|
|
276
|
+
// Remove all screens underneath visibleBottom && these marked for preload, but keep newTop.
|
|
277
|
+
screenWrappers
|
|
278
|
+
.asSequence()
|
|
279
|
+
.takeWhile { it !== visibleBottom }
|
|
280
|
+
.filter { (it !== newTop && !dismissedWrappers.contains(it)) || it.screen.activityState === Screen.ActivityState.INACTIVE }
|
|
281
|
+
.forEach { wrapper -> transaction.remove(wrapper.fragment) }
|
|
282
|
+
|
|
283
283
|
// attach screens that just became visible
|
|
284
284
|
if (visibleBottom != null && !visibleBottom.fragment.isAdded) {
|
|
285
285
|
val top = newTop
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
// ignore all screens beneath the visible bottom
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
continue
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
// when first visible screen found, make all screens after that visible
|
|
298
|
-
it.add(id, fragmentWrapper.fragment).runOnCommit {
|
|
299
|
-
top?.screen?.bringToFront()
|
|
286
|
+
screenWrappers
|
|
287
|
+
.asSequence()
|
|
288
|
+
.dropWhile { it !== visibleBottom } // ignore all screens beneath the visible bottom
|
|
289
|
+
.forEach { wrapper ->
|
|
290
|
+
// TODO: It should be enough to dispatch this on commit action once.
|
|
291
|
+
transaction.add(id, wrapper.fragment).runOnCommit {
|
|
292
|
+
top?.screen?.bringToFront()
|
|
293
|
+
}
|
|
300
294
|
}
|
|
301
|
-
}
|
|
302
295
|
} else if (newTop != null && !newTop.fragment.isAdded) {
|
|
303
296
|
if (!BuildConfig.IS_NEW_ARCHITECTURE_ENABLED && newTop.screen.isSheetFitToContents()) {
|
|
304
297
|
// On old architecture the content wrapper might not have received its frame yet,
|
|
@@ -306,15 +299,14 @@ class ScreenStack(
|
|
|
306
299
|
// we delay the transition and trigger it after views receive the layout.
|
|
307
300
|
newTop.fragment.postponeEnterTransition()
|
|
308
301
|
}
|
|
309
|
-
|
|
302
|
+
transaction.add(id, newTop.fragment)
|
|
310
303
|
}
|
|
311
304
|
topScreenWrapper = newTop as? ScreenStackFragmentWrapper
|
|
312
305
|
stack.clear()
|
|
313
|
-
stack.addAll(screenWrappers.map { it as ScreenStackFragmentWrapper })
|
|
306
|
+
stack.addAll(screenWrappers.asSequence().map { it as ScreenStackFragmentWrapper })
|
|
314
307
|
|
|
315
308
|
turnOffA11yUnderTransparentScreen(visibleBottom)
|
|
316
|
-
|
|
317
|
-
it.commitNowAllowingStateLoss()
|
|
309
|
+
transaction.commitNowAllowingStateLoss()
|
|
318
310
|
}
|
|
319
311
|
}
|
|
320
312
|
|
|
@@ -346,23 +338,6 @@ class ScreenStack(
|
|
|
346
338
|
stack.forEach { it.onContainerUpdate() }
|
|
347
339
|
}
|
|
348
340
|
|
|
349
|
-
// below methods are taken from
|
|
350
|
-
// https://github.com/airbnb/native-navigation/blob/9cf50bf9b751b40778f473f3b19fcfe2c4d40599/lib/android/src/main/java/com/airbnb/android/react/navigation/ScreenCoordinatorLayout.java#L43
|
|
351
|
-
// and are used to swap the order of drawing views when navigating forward with the transitions
|
|
352
|
-
// that are making transitioning fragments appear one on another. See more info in the comment to
|
|
353
|
-
// the linked class.
|
|
354
|
-
override fun removeView(view: View) {
|
|
355
|
-
// we set this property to reverse the order of drawing views
|
|
356
|
-
// when we want to push new fragment on top of the previous one and their animations collide.
|
|
357
|
-
// More information in:
|
|
358
|
-
// https://github.com/airbnb/native-navigation/blob/9cf50bf9b751b40778f473f3b19fcfe2c4d40599/lib/android/src/main/java/com/airbnb/android/react/navigation/ScreenCoordinatorLayout.java#L17
|
|
359
|
-
if (isDetachingCurrentScreen) {
|
|
360
|
-
isDetachingCurrentScreen = false
|
|
361
|
-
reverseLastTwoChildren = true
|
|
362
|
-
}
|
|
363
|
-
super.removeView(view)
|
|
364
|
-
}
|
|
365
|
-
|
|
366
341
|
private fun drawAndRelease() {
|
|
367
342
|
// We make a copy of the drawingOps and use it to dispatch draws in order to be sure
|
|
368
343
|
// that we do not modify the original list. There are cases when `op.draw` can call
|
|
@@ -381,12 +356,12 @@ class ScreenStack(
|
|
|
381
356
|
|
|
382
357
|
// check the view removal is completed (by comparing the previous children count)
|
|
383
358
|
if (drawingOps.size < previousChildrenCount) {
|
|
384
|
-
|
|
359
|
+
childDrawingOrderStrategy = null
|
|
385
360
|
}
|
|
386
361
|
previousChildrenCount = drawingOps.size
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
362
|
+
|
|
363
|
+
childDrawingOrderStrategy?.apply(drawingOps)
|
|
364
|
+
|
|
390
365
|
drawAndRelease()
|
|
391
366
|
}
|
|
392
367
|
|
|
@@ -415,7 +390,7 @@ class ScreenStack(
|
|
|
415
390
|
// See: https://developer.android.com/about/versions/15/behavior-changes-15?hl=en#openjdk-api-changes
|
|
416
391
|
private fun obtainDrawingOp(): DrawingOp = if (drawingOpPool.isEmpty()) DrawingOp() else drawingOpPool.removeAt(drawingOpPool.lastIndex)
|
|
417
392
|
|
|
418
|
-
|
|
393
|
+
internal inner class DrawingOp {
|
|
419
394
|
var canvas: Canvas? = null
|
|
420
395
|
var child: View? = null
|
|
421
396
|
var drawingTime: Long = 0
|