Skip to content

Commit 022ec00

Browse files
committed
change cutout inset handling in SAV and CustomToolbar
1 parent 204d8a5 commit 022ec00

File tree

3 files changed

+32
-26
lines changed

3 files changed

+32
-26
lines changed

android/src/main/java/com/swmansion/rnscreens/CustomToolbar.kt

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,21 +91,10 @@ open class CustomToolbar(
9191
// 3. edge-to-edge with translucent navigation buttons bar.
9292
//
9393
// Additionally we need to gracefully handle possible display cutouts.
94-
95-
// We use rootWindowInsets in lieu of insets or unhandledInsets here,
96-
// because cutout sometimes (only in certain scenarios, e.g. with headerLeft view present)
97-
// happen to be Insets.ZERO and is not reliable.
98-
val rootWindowInsets = rootWindowInsets
9994
val cutoutInsets =
100-
resolveInsetsOrZero(WindowInsetsCompat.Type.displayCutout(), rootWindowInsets)
95+
resolveInsetsOrZero(WindowInsetsCompat.Type.displayCutout(), unhandledInsets)
10196
val systemBarInsets =
102-
resolveInsetsOrZero(WindowInsetsCompat.Type.systemBars(), rootWindowInsets)
103-
val statusBarInsetsStable =
104-
resolveInsetsOrZero(
105-
WindowInsetsCompat.Type.systemBars(),
106-
rootWindowInsets,
107-
ignoreVisibility = true,
108-
)
97+
resolveInsetsOrZero(WindowInsetsCompat.Type.systemBars(), unhandledInsets)
10998

11099
// This seems to work fine in all tested configurations, because cutout & system bars overlap
111100
// only in portrait mode & top inset is controlled separately, therefore we don't count
@@ -124,7 +113,7 @@ open class CustomToolbar(
124113
val verticalInsets =
125114
InsetsCompat.of(
126115
0,
127-
max(cutoutInsets.top, if (shouldApplyTopInset) statusBarInsetsStable.top else 0),
116+
max(cutoutInsets.top, if (shouldApplyTopInset) systemBarInsets.top else 0),
128117
0,
129118
max(cutoutInsets.bottom, 0),
130119
)

android/src/main/java/com/swmansion/rnscreens/safearea/SafeAreaView.kt

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
package com.swmansion.rnscreens.safearea
44

55
import android.annotation.SuppressLint
6+
import android.os.Build
67
import android.util.Log
78
import android.view.View
89
import android.view.ViewTreeObserver
@@ -114,28 +115,41 @@ class SafeAreaView(
114115
}
115116
}
116117

117-
return WindowInsetsCompat
118+
var shouldConsumeDisplayCutout = false
119+
var consumedInsets = WindowInsetsCompat
118120
.Builder(insets)
119121
.apply {
120122
if (insetType.containsSystem()) {
123+
val consumedSystemBarsInsets = getConsumedInsetsFromSelectedEdges(
124+
insets.getInsets(
125+
WindowInsetsCompat.Type.systemBars(),
126+
))
127+
128+
val consumedDisplayCutoutInsets = getConsumedInsetsFromSelectedEdges(
129+
insets.getInsets(
130+
WindowInsetsCompat.Type.displayCutout()
131+
)
132+
)
133+
shouldConsumeDisplayCutout = consumedDisplayCutoutInsets == Insets.NONE
134+
121135
setInsets(
122136
WindowInsetsCompat.Type.systemBars(),
123-
getConsumedInsetsFromSelectedEdges(
124-
insets.getInsets(
125-
WindowInsetsCompat.Type.systemBars(),
126-
),
127-
),
137+
consumedSystemBarsInsets
128138
)
129139
setInsets(
130140
WindowInsetsCompat.Type.displayCutout(),
131-
getConsumedInsetsFromSelectedEdges(
132-
insets.getInsets(
133-
WindowInsetsCompat.Type.displayCutout(),
134-
),
135-
),
141+
consumedDisplayCutoutInsets
136142
)
137143
}
138144
}.build()
145+
146+
// On Android versions prior to R, setInsets(WindowInsetsCompat.Type.displayCutout(), ...)
147+
// does not work. We need to use previous API.
148+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R && shouldConsumeDisplayCutout) {
149+
consumedInsets = consumedInsets.consumeDisplayCutout()
150+
}
151+
152+
return consumedInsets
139153
}
140154

141155
private fun updateInsetsIfNeeded(): Boolean {

android/src/main/java/com/swmansion/rnscreens/utils/InsetsKt.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ internal fun View.resolveInsetsOrZero(
2222
return InsetsCompat.NONE
2323
}
2424

25-
val windowInsetsCompat = WindowInsetsCompat.toWindowInsetsCompat(sourceWindowInsets, this)
25+
// We don't use root view-aware WindowInsetsCompat to make sure we get information about display
26+
// cutout inset being consumed by one of the ancestor views. Refer to WindowInsetsCompat
27+
// `Impl20` implementation of getInsetsForType (case Type.DISPLAY_CUTOUT).
28+
val windowInsetsCompat = WindowInsetsCompat.toWindowInsetsCompat(sourceWindowInsets)
2629
return if (!ignoreVisibility) {
2730
windowInsetsCompat.getInsets(insetType)
2831
} else {

0 commit comments

Comments
 (0)