Commit ec7afd0
authored
fix(Android): fix draw ordering in transparent modal & stack nested in tabs interaction (#2647)
## Description
Fixes #2167
The exact error mechanism is **really** convoluted. The gist of it
however, and the issue cause lies in the fact
that our drawing / container updating logic worked under implicit (and
unspoken of) assumption that draw reordering would not be
applied for the transaction attaching very first screen in the stack.
Everything worked correctly until #2019 caused `needsDrawReordeing`
to return `true` **always when `Build.VERSION.SDK_INT > 33`** - and that
means pretty much **always** in new apps. Previously it returned
`false`,
in particular for the very first screen on stack because no one really
sets `stackAnimation` for the very first screen, since [it will have no
animation
anyway](https://github.com/software-mansion/react-native-screens/blob/c0b5586b7e645ed1d22143b5f84e0dd65dcd06be/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt#L137)
(and we might enforce this somewhere in JS code also, I'm not sure now).
This PR restores returning `false` there for first screen on the stack &
for any screen that uses `animation: 'none'`.
### Summary of the error mechanism
Consider following case:
```tsx
function App() {
return (
<Tabs>
<Screen A>
<Stack>
<Screen SA />
<Screen TM />
</Stack>
</Screen A>
<Screen B />
</Tabs>
);
}
```
Initially `Screen SA` is rendered. Basically when
[`isDetachingCurrentScreen`] was set for the very first screen (directly
because return value of `needsDrawReordeing`) and then
we navigated to other tab `Screen B` - we cause whole stack `Stack` to
be dropped & detached from window. Native callback
`onDetachedFromWindow` gets called in `ScreenContainer`,
we detach every fragment and subview (to prevent whole different class
of bugs) causing `removeView` callbacks in `ScreenStack`, leading to
`reverseLastTwoChildren` flag being set to `true`. When we then change
tab back to `Screen SA` in `Stack`
the drawing works as normal, because we have only one child. On
navigation to `Screen TM` (transparent modal) value of the
`reverseLastTwoChildren` flag causes the views to being drawn
in wrong order - transparent modal first and `Screen SA` second. In case
of not `transparent` presentation there is no issue, because `Screen SA`
would get
[detached](https://github.com/software-mansion/react-native-screens/blob/c0b5586b7e645ed1d22143b5f84e0dd65dcd06be/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt#L113-L115).
## Changes
Added param to `needsDrawReordeing` method informing of actual stack
animation in use (in case of first screen we always set it to `none`).
When there is no animation for the disappearing screen - there is no
need to change the draw ordering. Added appropriate code comment for the
future.
## Test code and steps to reproduce
`Test2167`
## Checklist
- [x] Included code example that can be used to test this change
- [x] Ensured that CI passes1 parent c0b5586 commit ec7afd0
3 files changed
Lines changed: 87 additions & 7 deletions
File tree
- android/src/main/java/com/swmansion/rnscreens
- apps/src/tests
Lines changed: 16 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
248 | 248 | | |
249 | 249 | | |
250 | 250 | | |
251 | | - | |
| 251 | + | |
252 | 252 | | |
253 | 253 | | |
254 | 254 | | |
| |||
258 | 258 | | |
259 | 259 | | |
260 | 260 | | |
| 261 | + | |
261 | 262 | | |
262 | 263 | | |
263 | 264 | | |
| |||
426 | 427 | | |
427 | 428 | | |
428 | 429 | | |
429 | | - | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
430 | 435 | | |
431 | 436 | | |
432 | 437 | | |
433 | | - | |
434 | | - | |
435 | | - | |
436 | | - | |
437 | | - | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
438 | 447 | | |
439 | 448 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
101 | 101 | | |
102 | 102 | | |
103 | 103 | | |
| 104 | + | |
104 | 105 | | |
105 | 106 | | |
106 | 107 | | |
| |||
0 commit comments