Skip to content

Large incorrect insets during rotation on Android #176

@TheAlmightyBob

Description

@TheAlmightyBob

During rotation on Android, react-native-safe-area-context can produce very large (varies by device, but in the hundreds) incorrect insets.

This can wind up breaking layouts in various ways, particularly where ScrollViews are involved (I'm not entirely certain what makes ScrollView so vulnerable).

I have a very simple Snack here: https://snack.expo.io/adtkzgDLf

If you start in portrait, you should see four lines of text. If you rotate to landscape, you should still see four lines of text. After rotating back to portrait, you may only see one line of text (there seem to be timing factors so it may take a couple tries...). It doesn't seem that snack has a view inspector, but when I've used that in other apps I saw that the reason for the missing views was that the views were abnormally tall... I'm guessing because the squashed width from the insets forced the Text elements to wordwrap. (I've seen other UI issues from this as well, the disappearing text elements is merely the simplest to repro/explain)

You can open the Expo Snack log window to see that the right and bottom insets being received are extremely large (they are then corrected back to zero, but it's still enough to create UI problems).

In some cases I've seen the UI recover but there was still a noticeable amount of relayout after rotation that would not normally occur.

This appears due to logic in SafeAreaUtils.getSafeAreaInsets:
https://github.com/th3rdwave/react-native-safe-area-context/blob/fc5ec123f05f5da5e02126c9e32057aa05105ead/android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaUtils.java#L59-L60

During the rotation, the windowWidth/windowHeight are updated to the new orientation before the current view's height/width are, so the current view's height/width can wind up being much larger than that of the window. Hence subtracting the window dimensions from the view dimensions still results in a very large number, which then becomes the inset.

I suspect this logic was only intended to handle cases where the current view was much smaller than (or offset from) the window, to avoid applying unnecessary insets? I can't imagine a scenario where you would actually want to increase the insets because the view extended past the window boundary? (even if that was a real issue, correcting it seems outside the responsibilities of this library)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions