Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Understanding WindowInsets - Android Worldwide

Understanding WindowInsets - Android Worldwide

Subhrajyoti Sen

July 26, 2021
Tweet

More Decks by Subhrajyoti Sen

Other Decks in Technology

Transcript

  1. Understanding
    WindowInsets
    KeepTruckin
    Subhrajyoti Sen Android Worldwide
    July 2021

    View Slide

  2. What are Insets?

    View Slide

  3. Insets - Types

    View Slide

  4. Insets - Types
    • Status Bars

    View Slide

  5. Insets - Types


    Status Bars
    Navigation Bars

    View Slide

  6. Insets - Types



    Status Bars
    Navigation Bars
    Caption Bar

    View Slide

  7. Insets - Types




    Status Bars
    Navigation Bars
    Caption Bar
    IME

    View Slide

  8. Insets - Types





    Status Bars
    Navigation Bars
    Caption Bar
    IME
    System Gestures

    View Slide

  9. Insets - Types






    Status Bars
    Navigation Bars
    Caption Bar
    IME
    System Gestures
    Display Cutouts

    View Slide

  10. Insets
    Status Bar
    Navigation Bar

    View Slide

  11. Improving the UI

    View Slide

  12. View Slide

  13. Going Full Screen
    view.systemUiVisibility =
    View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

    View Slide

  14. Going Full Screen
    view.systemUiVisibility =
    View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    On API 30+

    View Slide

  15. Going Full Screen
    window.setDecorFitsSystemWindows(false)
    On API 30+

    View Slide

  16. Going Full Screen
    WindowCompat.setDecorFitsSystemWindows(window, false)
    On API 30+ (backward compatible till API 21)

    View Slide

  17. Now we have full screen...but

    View Slide

  18. Before After

    View Slide

  19. Fetching WindowInsets

    View Slide

  20. Fetching WindowInsets
    binding.root.setOnApplyWindowInsetsListener { _, insets ->
    }

    View Slide

  21. Fetching WindowInsets
    binding.root.setOnApplyWindowInsetsListener { _, insets ->
    val navigationBarHeight =
    insets.getInsets()
    }

    View Slide

  22. Fetching WindowInsets
    binding.root.setOnApplyWindowInsetsListener { _, insets ->
    val navigationBarHeight =
    insets.getInsets(
    WindowInsets.Type.navigationBars()
    )
    }

    View Slide

  23. Fetching WindowInsets
    binding.root.setOnApplyWindowInsetsListener { _, insets ->
    val navigationBarHeight =
    insets.getInsets(
    WindowInsets.Type.navigationBars()
    ).bottom
    }

    View Slide

  24. Fetching WindowInsets
    binding.root.setOnApplyWindowInsetsListener { _, insets ->
    val navigationBarHeight =
    insets.getInsets(
    WindowInsets.Type.navigationBars()
    ).bottom
    (binding.root.layoutParams as? ViewGroup.MarginLayoutParams)?.
    bottomMargin = navigationBarHeight
    }

    View Slide

  25. Fetching WindowInsets
    insets.getInsets(WindowInsets.Type.navigationBars()).bottom
    On API 29+

    View Slide

  26. Fetching WindowInsets
    On API 21+

    View Slide

  27. Fetching WindowInsets
    WindowInsetsCompat
    .toWindowInsetsCompat(insets)
    .getInsets(
    WindowInsetsCompat.Type.navigationBars()
    ).bottom
    On API 21+

    View Slide

  28. Insetter to the rescue

    View Slide

  29. Insetter to the rescue
    Insetter.builder()
    .marginBottom(windowInsetTypesOf(navigationBars = true))
    .applyToView(rootView)

    View Slide

  30. Done

    View Slide

  31. Not yet...

    View Slide

  32. View Slide

  33. Introduce a notch

    View Slide

  34. View Slide

  35. Padding for Notch (Display Cutout)
    binding.root.setOnApplyWindowInsetsListener { _, insets ->
    notchHeight = WindowInsetsCompat.toWindowInsetsCompat(insets)
    .getInsets(WindowInsetsCompat.Type.displayCutout())
    .top
    }

    View Slide

  36. Padding for Notch (Display Cutout)
    binding.root.setOnApplyWindowInsetsListener { _, insets ->
    notchHeight = WindowInsetsCompat.toWindowInsetsCompat(insets)
    .getInsets(WindowInsetsCompat.Type.displayCutout())
    .top
    }

    View Slide

  37. Padding for Notch (Display Cutout)
    binding.root.setOnApplyWindowInsetsListener { _, insets ->
    notchHeight = WindowInsetsCompat.toWindowInsetsCompat(insets)
    .getInsets(WindowInsetsCompat.Type.displayCutout())
    .top
    }

    View Slide

  38. Padding for Notch (Display Cutout)
    binding.root.setOnApplyWindowInsetsListener { _, insets ->
    notchHeight = WindowInsetsCompat.toWindowInsetsCompat(insets)
    .getInsets(WindowInsetsCompat.Type.displayCutout())
    .top
    binding.toolbar.updatePadding(top= notchHeight)
    insets
    }

    View Slide

  39. Doing more with WindowInsets API

    View Slide

  40. Status Bar Appearance (Earlier)
    val decor = window.decorView
    decor.systemUiVisibility = decor.systemUiVisibility or
    View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
    Light status bar

    View Slide

  41. Status Bar Appearance (Earlier)
    val decor = window.decorView
    decor.systemUiVisibility = decor.systemUiVisibility or
    View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
    Dark status bar

    View Slide

  42. Status Bar Appearance (Earlier)
    val decor = window.decorView
    decor.systemUiVisibility = decor.systemUiVisibility or
    View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv()
    On API 30+

    View Slide

  43. Status Bar Appearance
    WindowCompat.getInsetsController(
    window,
    window.decorView
    )?.isAppearanceLightStatusBars = false
    On API 21+

    View Slide

  44. Show/Hide keyboard

    View Slide

  45. Show keyboard
    val controller = WindowCompat.getInsetsController(
    window,
    window.decorView
    )
    controller?.show(WindowInsetsCompat.Type.ime())

    View Slide

  46. Hide keyboard
    val controller = WindowCompat.getInsetsController(
    window,
    window.decorView
    )
    controller?.hide(WindowInsetsCompat.Type.ime())

    View Slide

  47. Hide status bar
    val controller = WindowCompat.getInsetsController(
    window,
    window.decorView
    )
    controller?.hide(WindowInsetsCompat.Type.statusBars())

    View Slide

  48. Check keyboard visibility
    binding.root.setOnApplyWindowInsetsListener { _, insets ->
    val visible = WindowInsetsCompat.toWindowInsetsCompat(insets)
    .isVisible(WindowInsetsCompat.Type.ime())
    }

    View Slide

  49. New APIs in Android 12

    View Slide

  50. Rounded Corners

    View Slide

  51. Rounded Corners
    android.view.RoundedCorner

    View Slide

  52. Rounded Corners
    android.view.RoundedCorner
    WindowInsets.getRoundedCorner(int position)

    View Slide

  53. Privacy Indicators

    View Slide

  54. Privacy Indicators
    WindowInsets.getPrivacyIndicatorBounds() : Rect

    View Slide

  55. @iamsubhrajyoti

    View Slide