SafeAreaUtils.java 2.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package com.th3rdwave.safeareacontext;
  2. import android.graphics.Rect;
  3. import android.os.Build;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import android.view.WindowInsets;
  7. import android.support.annotation.Nullable;
  8. /* package */ class SafeAreaUtils {
  9. private static @Nullable EdgeInsets getRootWindowInsetsCompat(View rootView) {
  10. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
  11. WindowInsets insets = rootView.getRootWindowInsets();
  12. if (insets == null) {
  13. return null;
  14. }
  15. return new EdgeInsets(
  16. insets.getSystemWindowInsetTop(),
  17. insets.getSystemWindowInsetRight(),
  18. insets.getSystemWindowInsetBottom(),
  19. insets.getSystemWindowInsetLeft());
  20. } else {
  21. Rect visibleRect = new Rect();
  22. rootView.getWindowVisibleDisplayFrame(visibleRect);
  23. return new EdgeInsets(
  24. visibleRect.top,
  25. rootView.getWidth() - visibleRect.right,
  26. rootView.getHeight() - visibleRect.bottom,
  27. visibleRect.left);
  28. }
  29. }
  30. static @Nullable EdgeInsets getSafeAreaInsets(View rootView, View view) {
  31. EdgeInsets windowInsets = getRootWindowInsetsCompat(rootView);
  32. if (windowInsets == null) {
  33. return null;
  34. }
  35. // Calculate the part of the view that overlaps with window insets.
  36. float windowWidth = rootView.getWidth();
  37. float windowHeight = rootView.getHeight();
  38. Rect visibleRect = new Rect();
  39. view.getGlobalVisibleRect(visibleRect);
  40. windowInsets.top = Math.max(windowInsets.top - visibleRect.top, 0);
  41. windowInsets.left = Math.max(windowInsets.left - visibleRect.left, 0);
  42. windowInsets.bottom = Math.max(visibleRect.top + view.getHeight() + windowInsets.bottom - windowHeight, 0);
  43. windowInsets.right = Math.max(visibleRect.left + view.getWidth() + windowInsets.right - windowWidth, 0);
  44. return windowInsets;
  45. }
  46. static @Nullable com.th3rdwave.safeareacontext.Rect getFrame(ViewGroup rootView, View view) {
  47. // This can happen while the view gets unmounted.
  48. if (view.getParent() == null) {
  49. return null;
  50. }
  51. Rect offset = new Rect();
  52. view.getDrawingRect(offset);
  53. try {
  54. rootView.offsetDescendantRectToMyCoords(view, offset);
  55. } catch (IllegalArgumentException ex) {
  56. // This can throw if the view is not a descendant of rootView. This should not
  57. // happen but avoid potential crashes.
  58. ex.printStackTrace();
  59. return null;
  60. }
  61. return new com.th3rdwave.safeareacontext.Rect(offset.left, offset.top, view.getWidth(), view.getHeight());
  62. }
  63. }