|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+package com.th3rdwave.safeareaview;
|
|
|
2
|
+
|
|
|
3
|
+import android.content.Context;
|
|
|
4
|
+import android.os.Build;
|
|
|
5
|
+import android.util.DisplayMetrics;
|
|
|
6
|
+import android.view.Surface;
|
|
|
7
|
+import android.view.WindowInsets;
|
|
|
8
|
+import android.view.WindowManager;
|
|
|
9
|
+
|
|
|
10
|
+import com.facebook.infer.annotation.Assertions;
|
|
|
11
|
+import com.facebook.react.uimanager.DisplayMetricsHolder;
|
|
|
12
|
+import com.facebook.react.views.view.ReactViewGroup;
|
|
|
13
|
+
|
|
|
14
|
+import androidx.annotation.Nullable;
|
|
|
15
|
+
|
|
|
16
|
+public class SafeAreaView extends ReactViewGroup {
|
|
|
17
|
+ public interface OnInsetsChangeListener {
|
|
|
18
|
+ void onInsetsChange(SafeAreaView view, EdgeInsets insets);
|
|
|
19
|
+ }
|
|
|
20
|
+
|
|
|
21
|
+ private @Nullable OnInsetsChangeListener mInsetsChangeListener;
|
|
|
22
|
+ WindowManager mWindowManager;
|
|
|
23
|
+
|
|
|
24
|
+ public SafeAreaView(Context context) {
|
|
|
25
|
+ super(context);
|
|
|
26
|
+
|
|
|
27
|
+ mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
|
|
|
28
|
+ }
|
|
|
29
|
+
|
|
|
30
|
+ private EdgeInsets getSafeAreaInsets() {
|
|
|
31
|
+ // Window insets are parts of the window that are covered by system views (status bar,
|
|
|
32
|
+ // navigation bar, notches). There are no apis the get these values for android < M so we
|
|
|
33
|
+ // do a best effort polyfill.
|
|
|
34
|
+ EdgeInsets windowInsets;
|
|
|
35
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
36
|
+ WindowInsets insets = getRootWindowInsets();
|
|
|
37
|
+ windowInsets = new EdgeInsets(
|
|
|
38
|
+ insets.getSystemWindowInsetTop(),
|
|
|
39
|
+ insets.getSystemWindowInsetRight(),
|
|
|
40
|
+ insets.getSystemWindowInsetBottom(),
|
|
|
41
|
+ insets.getSystemWindowInsetLeft());
|
|
|
42
|
+ } else {
|
|
|
43
|
+ int rotation = mWindowManager.getDefaultDisplay().getRotation();
|
|
|
44
|
+ int statusBarHeight = 0;
|
|
|
45
|
+ int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
|
|
|
46
|
+ if (resourceId > 0) {
|
|
|
47
|
+ statusBarHeight = getResources().getDimensionPixelSize(resourceId);
|
|
|
48
|
+ }
|
|
|
49
|
+ int navbarHeight = 0;
|
|
|
50
|
+ resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
|
|
|
51
|
+ if (resourceId > 0) {
|
|
|
52
|
+ navbarHeight = getResources().getDimensionPixelSize(resourceId);
|
|
|
53
|
+ }
|
|
|
54
|
+
|
|
|
55
|
+ windowInsets = new EdgeInsets(
|
|
|
56
|
+ statusBarHeight,
|
|
|
57
|
+ rotation == Surface.ROTATION_90 ? navbarHeight : 0,
|
|
|
58
|
+ rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? navbarHeight : 0,
|
|
|
59
|
+ rotation == Surface.ROTATION_270 ? navbarHeight : 0);
|
|
|
60
|
+ }
|
|
|
61
|
+
|
|
|
62
|
+ // Calculate the part of the root view that overlaps with window insets.
|
|
|
63
|
+ int[] windowLocation = new int[2];
|
|
|
64
|
+ getLocationInWindow(windowLocation);
|
|
|
65
|
+ DisplayMetrics screenMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();
|
|
|
66
|
+ windowInsets.top = Math.max(windowInsets.top - windowLocation[1], 0);
|
|
|
67
|
+ windowInsets.left = Math.max(windowInsets.left - windowLocation[0], 0);
|
|
|
68
|
+ windowInsets.bottom = Math.max(windowLocation[1] + getHeight() + windowInsets.bottom - screenMetrics.heightPixels, 0);
|
|
|
69
|
+ windowInsets.right = Math.max(windowLocation[0] + getWidth() + windowInsets.right - screenMetrics.widthPixels, 0);
|
|
|
70
|
+ return windowInsets;
|
|
|
71
|
+ }
|
|
|
72
|
+
|
|
|
73
|
+ @Override
|
|
|
74
|
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
|
75
|
+ super.onLayout(changed, left, top, right, bottom);
|
|
|
76
|
+
|
|
|
77
|
+ Assertions.assertNotNull(mInsetsChangeListener).onInsetsChange(this, getSafeAreaInsets());
|
|
|
78
|
+ }
|
|
|
79
|
+
|
|
|
80
|
+ public void setOnInsetsChangeListener(OnInsetsChangeListener listener) {
|
|
|
81
|
+ mInsetsChangeListener = listener;
|
|
|
82
|
+ }
|
|
|
83
|
+}
|