feat(Android,Fabric): add FullWindowOverlay support for Android
Description
Closes: https://github.com/software-mansion/react-native-screens-labs/issues/660
[!note] @kkafar: Hey, the progress here was halted because IIRC there was no good way to achieve desired behaviour. Namely if I presented the FWO component as Dialog, any other Dialog presented afterwards would be displayed above FWO overlay. Which is undesirable. IIRC there was also an option to display some content literally above everything else, but that included whole application & potentially different applications (I think that was feature meant for screen recording apps etc.). Additionally this mode required explicit permission from application user, therefore introducing another undesirable characteristic.
I don't rule out future proceeding on this PR / exploring different options but currently we >don't have it in active backlog.
This PR aims to add experimental support for FullWindowOverlay component on Android.
Supersedes #2421, #2425 (shoutout to @maciekstosio & @mfazekas for the initial work & research)
State:
- [x] Edge-to-edge (targetSdk >= 35)
- [ ] regular (targetSdk < 35)
- [x] screen orientation change
- [x] gesture support for items in FWO subtree
- [x] pointer events (including hover)
- [x] blocks gestures in main tree
- [x] pointer events (including hover)
- [x] react modal interaction tested & described
- [ ] interaction with our modals
- [x] Android (formSheet stays underneath)
- [ ] iOS
Description copied from the "docs" I've added for this component in this PR
FullWindowOverlay
[!caution] Support of this component on Android is currently experimental and limited to new architecture.
In addition to navigation primitives described above :point_up:, the library exposes FullWindowOverlay component. Its purpose is to enable displaying overlay above all other application contents.
Example usage can be found in TestFullWindowOverlay example in our test app.
Below we shortly describe current characteristics of the component.
[!note] Description below should be treated as implementation details and not as stable behavior description, unless explicitly stated otherwise.
View hierarchy placement
On both platforms - iOS & Android the FullWindowOverlay component gives you opportunity to mount your views directly under UIWindow & Window respectively.
This allows for presenting the content above all main application content.
When using FullWindowOverlay the views are mounted in a subtree separate from main react-native subtree. This has some diverging behavior implications for each platform. Please see below the behavior description.
Behavior aspects
[!note] Description below should be treated as implementation details and not as stable behavior description, unless explicitly stated otherwise.
Dimensions
FullWindowOverlay should have dimensions of full window. It does not take safe area insets into account - it is left to the user to handle.
In Android applications that do not have edge-to-edge enabled (vast majority of applications targeting SDK 34 or lower) the status & navigation bars are expected.
Gestures
By design, the FullWindowOverlay component blocks gesture interaction with content underneath.
The gestures for views in FullWindowOverlay's subtree are fully supported.
Interaction with modal components
In this section we describe briefly how the FullWindowOverlay component behaves when used simultaneously with different modal components.
Due to platform differences the behavior is slightly different depending whether it is used on iOS or Android devices.
iOS
On iOS the FullWindowOverlay stays above navigation screens with modal presentation. The same applies for e.g. Modal from react-native. We do not guarantee that
this will be the case for any third-party modal component, since it depends on its internal implementation.
Android
On Android we use TYPE_APPLICATION_ATTACHED_DIALOG to mount
the component directly under the window. Together with react-native's Modal implementation details this implies that Modal will be displayed above the FullWindowOverlay
if displayed from already mounted FullWindowOverlay - and vice versa -FullWindowOverlay will be displayed above the Modal if displayed from already mounted Modal.
To make FullWindowOverlay display always on top of everything on Android is technically possible, however requires explicit permission from the application user. At the moment we decided
to avoid this and settled on "weaker" implementation. Please note that we might add this option some time in the future (in a non-breaking way).
and back to PR description...
Changes
Test code and steps to reproduce
Test1096, TestFullWindowOverlay
Checklist
- [ ] Included code example that can be used to test this change
- [ ] Ensured that CI passes
Currently blocked by a layout bug when changing screen orientation on Android SDK 34.
Any progress on this? Would love support for this :)
Are you still blocked?
Hey @mrmuke, I haven't look into this PR since. This still requires some debugging work & refactor to use Dialog. I might be able to be back at it after release of stable 4.11.0
Any progress on this? would this allow nested formSheets / modals on Android to display over the parent components it's nested with / under? as they do in iOS?
unsure if this is an issue with screens or expo router tho but this does look promising
Hey, the progress here was halted because IIRC there was no good way to achieve desired behaviour. Namely if I presented the FWO component as Dialog, any other Dialog presented afterwards would be displayed above FWO overlay. Which is undesirable. IIRC there was also an option to display some content literally above everything else, but that included whole application & potentially different applications (I think that was feature meant for screen recording apps etc.). Additionally this mode required explicit permission from application user, therefore introducing another undesirable characteristic.
I don't rule out future proceeding on this PR / exploring different options but currently we don't have it in active backlog.