Browse Source

Use getWindowVisibleDisplayFrame to calculate edge insets on api < 20

Janic Duplessis 4 years ago
parent
commit
12da572a91

+ 16
- 28
android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaUtils.java View File

@@ -2,52 +2,40 @@ package com.th3rdwave.safeareacontext;
2 2
 
3 3
 import android.graphics.Rect;
4 4
 import android.os.Build;
5
-import android.view.Surface;
6 5
 import android.view.View;
7 6
 import android.view.ViewGroup;
8 7
 import android.view.WindowInsets;
9
-import android.view.WindowManager;
10 8
 
11 9
 import androidx.annotation.Nullable;
12 10
 
13 11
 /* package */ class SafeAreaUtils {
14
-  static @Nullable EdgeInsets getSafeAreaInsets(
15
-      WindowManager windowManager,
16
-      View rootView,
17
-      View view
18
-  ) {
19
-    // Window insets are parts of the window that are covered by system views (status bar,
20
-    // navigation bar, notches). There are no apis the get these values for android < M so we
21
-    // do a best effort polyfill.
22
-    EdgeInsets windowInsets;
12
+
13
+  private static @Nullable EdgeInsets getRootWindowInsetsCompat(View rootView) {
23 14
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
24 15
       WindowInsets insets = rootView.getRootWindowInsets();
25 16
       if (insets == null) {
26 17
         return null;
27 18
       }
28
-      windowInsets = new EdgeInsets(
19
+      return new EdgeInsets(
29 20
           insets.getSystemWindowInsetTop(),
30 21
           insets.getSystemWindowInsetRight(),
31 22
           insets.getSystemWindowInsetBottom(),
32 23
           insets.getSystemWindowInsetLeft());
33 24
     } else {
34
-      int rotation = windowManager.getDefaultDisplay().getRotation();
35
-      int statusBarHeight = 0;
36
-      int resourceId = rootView.getResources().getIdentifier("status_bar_height", "dimen", "android");
37
-      if (resourceId > 0) {
38
-        statusBarHeight = rootView.getResources().getDimensionPixelSize(resourceId);
39
-      }
40
-      int navbarHeight = 0;
41
-      resourceId = rootView.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
42
-      if (resourceId > 0) {
43
-        navbarHeight = rootView.getResources().getDimensionPixelSize(resourceId);
44
-      }
25
+      Rect visibleRect = new Rect();
26
+      rootView.getWindowVisibleDisplayFrame(visibleRect);
27
+      return new EdgeInsets(
28
+          visibleRect.top,
29
+          rootView.getWidth() - visibleRect.right,
30
+          rootView.getHeight() - visibleRect.bottom,
31
+          visibleRect.left);
32
+    }
33
+  }
45 34
 
46
-      windowInsets = new EdgeInsets(
47
-          statusBarHeight,
48
-          rotation == Surface.ROTATION_90 ? navbarHeight : 0,
49
-          rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? navbarHeight : 0,
50
-          rotation == Surface.ROTATION_270 ? navbarHeight : 0);
35
+  static @Nullable EdgeInsets getSafeAreaInsets(View rootView, View view) {
36
+    EdgeInsets windowInsets = getRootWindowInsetsCompat(rootView);
37
+    if (windowInsets == null) {
38
+      return null;
51 39
     }
52 40
 
53 41
     // Calculate the part of the view that overlaps with window insets.

+ 2
- 6
android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaView.java View File

@@ -4,7 +4,6 @@ import android.annotation.SuppressLint;
4 4
 import android.content.Context;
5 5
 import android.view.ViewGroup;
6 6
 import android.view.ViewTreeObserver;
7
-import android.view.WindowManager;
8 7
 
9 8
 import com.facebook.infer.annotation.Assertions;
10 9
 import com.facebook.react.views.view.ReactViewGroup;
@@ -18,18 +17,15 @@ public class SafeAreaView extends ReactViewGroup implements ViewTreeObserver.OnG
18 17
   }
19 18
 
20 19
   private @Nullable OnInsetsChangeListener mInsetsChangeListener;
21
-  private final WindowManager mWindowManager;
22 20
   private @Nullable EdgeInsets mLastInsets;
23 21
   private @Nullable Rect mLastFrame;
24 22
 
25
-  public SafeAreaView(Context context, WindowManager windowManager) {
23
+  public SafeAreaView(Context context) {
26 24
     super(context);
27
-
28
-    mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
29 25
   }
30 26
 
31 27
   private void maybeUpdateInsets() {
32
-    EdgeInsets edgeInsets = SafeAreaUtils.getSafeAreaInsets(mWindowManager, getRootView(), this);
28
+    EdgeInsets edgeInsets = SafeAreaUtils.getSafeAreaInsets(getRootView(), this);
33 29
     Rect frame = SafeAreaUtils.getFrame((ViewGroup) getRootView(), this);
34 30
     if (edgeInsets != null && frame != null &&
35 31
         (mLastInsets == null ||

+ 2
- 9
android/src/main/java/com/th3rdwave/safeareacontext/SafeAreaViewManager.java View File

@@ -1,10 +1,8 @@
1 1
 package com.th3rdwave.safeareacontext;
2 2
 
3 3
 import android.app.Activity;
4
-import android.content.Context;
5 4
 import android.view.View;
6 5
 import android.view.ViewGroup;
7
-import android.view.WindowManager;
8 6
 
9 7
 import com.facebook.react.bridge.ReactApplicationContext;
10 8
 import com.facebook.react.common.MapBuilder;
@@ -20,13 +18,11 @@ import androidx.annotation.Nullable;
20 18
 
21 19
 public class SafeAreaViewManager extends ViewGroupManager<SafeAreaView> {
22 20
   private final ReactApplicationContext mContext;
23
-  private final WindowManager mWindowManager;
24 21
 
25 22
   public SafeAreaViewManager(ReactApplicationContext context) {
26 23
     super();
27 24
 
28 25
     mContext = context;
29
-    mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
30 26
   }
31 27
 
32 28
   @Override
@@ -38,7 +34,7 @@ public class SafeAreaViewManager extends ViewGroupManager<SafeAreaView> {
38 34
   @Override
39 35
   @NonNull
40 36
   public SafeAreaView createViewInstance(@NonNull ThemedReactContext context) {
41
-    return new SafeAreaView(context, mWindowManager);
37
+    return new SafeAreaView(context);
42 38
   }
43 39
 
44 40
   @Override
@@ -74,10 +70,7 @@ public class SafeAreaViewManager extends ViewGroupManager<SafeAreaView> {
74 70
     }
75 71
 
76 72
     View contentView = decorView.findViewById(android.R.id.content);
77
-    EdgeInsets insets = SafeAreaUtils.getSafeAreaInsets(
78
-        mWindowManager,
79
-        decorView,
80
-        contentView);
73
+    EdgeInsets insets = SafeAreaUtils.getSafeAreaInsets(decorView, contentView);
81 74
     Rect frame = SafeAreaUtils.getFrame(decorView, contentView);
82 75
     if (insets == null || frame == null) {
83 76
       return null;

+ 2
- 1
package.json View File

@@ -27,7 +27,8 @@
27 27
     "validate:typescript": "tsc --project ./ --noEmit",
28 28
     "validate:prettier": "prettier \"src/**/*.{js,ts,tsx}\" \"example/**/*.{js,ts,tsx}\" --check",
29 29
     "validate:jest": "jest",
30
-    "prepare": "bob build"
30
+    "prepare": "bob build",
31
+    "example:ios": "cd example && react-native run-ios"
31 32
   },
32 33
   "keywords": [
33 34
     "react-native",

+ 1
- 1
src/index.tsx View File

@@ -1,4 +1,4 @@
1 1
 export * from './SafeAreaContext';
2 2
 export * from './SafeAreaView';
3
-export * from './initialWindowMetrics';
3
+export * from './InitialWindow';
4 4
 export * from './SafeArea.types';