Skip to content

Commit 6ce1275

Browse files
authored
fix: Android safe areas should work when there are no cutouts (#3926)
This fixes #3925, where it was demonstrated that the Sheet was being cut off by the bottom navigation bar. I found that the current code for updating the safe area would always return zero insets if the device didn't have a cutout. Fixed it so that system bars would still be incorporated into the safe area even with there were no cutouts.
1 parent d34a23f commit 6ce1275

File tree

1 file changed

+54
-51
lines changed

1 file changed

+54
-51
lines changed

Ports/Android/src/com/codename1/impl/android/CodenameOneView.java

Lines changed: 54 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ public void visibilityChangedTo(boolean visible) {
164164

165165
private void updateSafeArea() {
166166
final Activity activity = CodenameOneView.this.implementation.getActivity();
167-
168167
final Rect rect = this.safeArea;
169168
final View rootView = activity.getWindow().getDecorView();
170169
if (Build.VERSION.SDK_INT >= VERSION_CODE_P) {
@@ -176,69 +175,73 @@ private void updateSafeArea() {
176175
Method getDisplayCutoutMethod = windowInsetsClass.getMethod("getDisplayCutout");
177176
Object cutout = getDisplayCutoutMethod.invoke(insets);
178177

178+
int left = 0;
179+
int top = 0;
180+
int right = 0;
181+
int bottom = 0;
179182
if (cutout != null) {
180183
Class<?> displayCutoutClass = Class.forName("android.view.DisplayCutout");
181184
Method getSafeInsetLeft = displayCutoutClass.getMethod("getSafeInsetLeft");
182185
Method getSafeInsetTop = displayCutoutClass.getMethod("getSafeInsetTop");
183186
Method getSafeInsetRight = displayCutoutClass.getMethod("getSafeInsetRight");
184187
Method getSafeInsetBottom = displayCutoutClass.getMethod("getSafeInsetBottom");
188+
left = ((Integer) getSafeInsetLeft.invoke(cutout)).intValue();
189+
top = ((Integer) getSafeInsetTop.invoke(cutout)).intValue();
190+
right = ((Integer) getSafeInsetRight.invoke(cutout)).intValue();
191+
bottom = ((Integer) getSafeInsetBottom.invoke(cutout)).intValue();
192+
}
185193

186-
int left = ((Integer) getSafeInsetLeft.invoke(cutout)).intValue();
187-
int top = ((Integer) getSafeInsetTop.invoke(cutout)).intValue();
188-
int right = ((Integer) getSafeInsetRight.invoke(cutout)).intValue();
189-
int bottom = ((Integer) getSafeInsetBottom.invoke(cutout)).intValue();
190-
boolean imeVisible = false;
191-
try {
192-
Method isVisibleMethod = insets.getClass().getMethod("isVisible", int.class);
193-
Class<?> typeClass = Class.forName("android.view.WindowInsets$Type");
194-
int imeType = ((Integer) typeClass.getMethod("ime").invoke(null)).intValue();
195-
imeVisible = (Boolean) isVisibleMethod.invoke(insets, imeType);
196-
} catch (Throwable t) {
197-
// Fallback or log
198-
}
194+
boolean imeVisible = false;
195+
try {
196+
Method isVisibleMethod = insets.getClass().getMethod("isVisible", int.class);
197+
Class<?> typeClass = Class.forName("android.view.WindowInsets$Type");
198+
int imeType = ((Integer) typeClass.getMethod("ime").invoke(null)).intValue();
199+
imeVisible = (Boolean) isVisibleMethod.invoke(insets, imeType);
200+
} catch (Throwable t) {
201+
// Fallback or log
202+
}
199203

200-
Rect systemBarInsets = AndroidImplementation.getSystemBarInsets(rootView);
201-
top = Math.max(systemBarInsets.top, top);
202-
if (imeVisible) {
203-
// Avoid double-counting the bottom gesture bar
204-
bottom = Math.max(bottom, 0);
205-
} else {
206-
bottom = Math.max(systemBarInsets.bottom, bottom);
207-
}
208-
left = Math.max(systemBarInsets.left, left);
209-
right = Math.max(systemBarInsets.right, right);
210-
211-
if (!AndroidImplementation.isImmersive()) {
212-
top -= systemBarInsets.top;
213-
if (!imeVisible) {
214-
bottom -= systemBarInsets.bottom;
215-
}
216-
left -= systemBarInsets.left;
217-
right -= systemBarInsets.right;
204+
Rect systemBarInsets = AndroidImplementation.getSystemBarInsets(rootView);
205+
top = Math.max(systemBarInsets.top, top);
206+
if (imeVisible) {
207+
// Avoid double-counting the bottom gesture bar
208+
bottom = Math.max(bottom, 0);
209+
} else {
210+
bottom = Math.max(systemBarInsets.bottom, bottom);
211+
}
212+
left = Math.max(systemBarInsets.left, left);
213+
right = Math.max(systemBarInsets.right, right);
214+
215+
if (!AndroidImplementation.isImmersive()) {
216+
top -= systemBarInsets.top;
217+
if (!imeVisible) {
218+
bottom -= systemBarInsets.bottom;
218219
}
220+
left -= systemBarInsets.left;
221+
right -= systemBarInsets.right;
222+
}
219223

220-
// Only apply if at least one is non-zero
221-
if (left != 0 || top != 0 || right != 0 || bottom != 0) {
222-
boolean isChanged = rect.left != left
223-
|| rect.right != right
224-
|| rect.top != top
225-
|| rect.bottom != bottom;
226-
rect.left = left;
227-
rect.top = top;
228-
rect.right = right;
229-
rect.bottom = bottom;
230-
231-
if (isChanged) {
232-
Display.getInstance().callSerially(new Runnable() {
233-
public void run() {
234-
AndroidImplementation.getInstance().revalidate();
235-
}
236-
});
237-
}
224+
// Only apply if at least one is non-zero
225+
if (left != 0 || top != 0 || right != 0 || bottom != 0) {
226+
boolean isChanged = rect.left != left
227+
|| rect.right != right
228+
|| rect.top != top
229+
|| rect.bottom != bottom;
230+
rect.left = left;
231+
rect.top = top;
232+
rect.right = right;
233+
rect.bottom = bottom;
234+
235+
if (isChanged) {
236+
Display.getInstance().callSerially(new Runnable() {
237+
public void run() {
238+
AndroidImplementation.getInstance().revalidate();
239+
}
240+
});
238241
}
239242
}
240243
}
241-
} catch (Exception e) {
244+
} catch (Throwable e) {
242245
rect.top = 0;
243246
rect.left = 0;
244247
rect.right = 0;

0 commit comments

Comments
 (0)