No Description

SafeAreaUtils.java 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package com.th3rdwave.safeareacontext;
  2. import android.graphics.Rect;
  3. import android.os.Build;
  4. import android.view.Surface;
  5. import android.view.View;
  6. import android.view.WindowInsets;
  7. import android.view.WindowManager;
  8. import com.facebook.react.bridge.Arguments;
  9. import com.facebook.react.bridge.WritableMap;
  10. import com.facebook.react.common.MapBuilder;
  11. import com.facebook.react.uimanager.PixelUtil;
  12. import java.util.Map;
  13. import android.support.annotation.Nullable;
  14. /* package */ class SafeAreaUtils {
  15. static WritableMap edgeInsetsToJsMap(EdgeInsets insets) {
  16. WritableMap insetsMap = Arguments.createMap();
  17. insetsMap.putDouble("top", PixelUtil.toDIPFromPixel(insets.top));
  18. insetsMap.putDouble("right", PixelUtil.toDIPFromPixel(insets.right));
  19. insetsMap.putDouble("bottom", PixelUtil.toDIPFromPixel(insets.bottom));
  20. insetsMap.putDouble("left", PixelUtil.toDIPFromPixel(insets.left));
  21. return insetsMap;
  22. }
  23. static Map<String, Float> edgeInsetsToJavaMap(EdgeInsets insets) {
  24. return MapBuilder.of(
  25. "top",
  26. PixelUtil.toDIPFromPixel(insets.top),
  27. "right",
  28. PixelUtil.toDIPFromPixel(insets.right),
  29. "bottom",
  30. PixelUtil.toDIPFromPixel(insets.bottom),
  31. "left",
  32. PixelUtil.toDIPFromPixel(insets.left));
  33. }
  34. static @Nullable EdgeInsets getSafeAreaInsets(WindowManager windowManager, View rootView) {
  35. // Window insets are parts of the window that are covered by system views (status bar,
  36. // navigation bar, notches). There are no apis the get these values for android < M so we
  37. // do a best effort polyfill.
  38. EdgeInsets windowInsets;
  39. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  40. WindowInsets insets = rootView.getRootWindowInsets();
  41. if (insets == null) {
  42. return null;
  43. }
  44. windowInsets = new EdgeInsets(
  45. insets.getSystemWindowInsetTop(),
  46. insets.getSystemWindowInsetRight(),
  47. insets.getSystemWindowInsetBottom(),
  48. insets.getSystemWindowInsetLeft());
  49. } else {
  50. int rotation = windowManager.getDefaultDisplay().getRotation();
  51. int statusBarHeight = 0;
  52. int resourceId = rootView.getResources().getIdentifier("status_bar_height", "dimen", "android");
  53. if (resourceId > 0) {
  54. statusBarHeight = rootView.getResources().getDimensionPixelSize(resourceId);
  55. }
  56. int navbarHeight = 0;
  57. resourceId = rootView.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
  58. if (resourceId > 0) {
  59. navbarHeight = rootView.getResources().getDimensionPixelSize(resourceId);
  60. }
  61. windowInsets = new EdgeInsets(
  62. statusBarHeight,
  63. rotation == Surface.ROTATION_90 ? navbarHeight : 0,
  64. rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? navbarHeight : 0,
  65. rotation == Surface.ROTATION_270 ? navbarHeight : 0);
  66. }
  67. // Calculate the part of the root view that overlaps with window insets.
  68. View contentView = rootView.findViewById(android.R.id.content);
  69. float windowWidth = rootView.getWidth();
  70. float windowHeight = rootView.getHeight();
  71. Rect visibleRect = new Rect();
  72. contentView.getGlobalVisibleRect(visibleRect);
  73. windowInsets.top = Math.max(windowInsets.top - visibleRect.top, 0);
  74. windowInsets.left = Math.max(windowInsets.left - visibleRect.left, 0);
  75. windowInsets.bottom = Math.max(visibleRect.top + contentView.getHeight() + windowInsets.bottom - windowHeight, 0);
  76. windowInsets.right = Math.max(visibleRect.left + contentView.getWidth() + windowInsets.right - windowWidth, 0);
  77. return windowInsets;
  78. }
  79. }