ActionBar crop in cutout area

339 views Asked by At

When I use fullscreen with cutout, i have next screen. How fix this?

Cutout:

window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES

Fullscreen:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    if (visible) {
        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                )
    } else {
        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // прячем панель навигации
                or View.SYSTEM_UI_FLAG_FULLSCREEN // прячем строку состояния
                or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
    }
}

Transparent

val color = ContextCompat.getColor(this, R.color.transparent_dark)
window.statusBarColor = color
window.navigationBarColor = color

ActionBar by default (not custom Toolbar):

<style name="AppTheme.Viewer" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="windowActionModeOverlay">true</item>
    <item name="actionBarStyle">@style/MyTheme.ActionBar</item>
</style>

<style name="MyTheme.ActionBar" parent="Widget.AppCompat.ActionBar">
    <item name="elevation" tools:targetApi="lollipop">0dp</item>
    <item name="background">@color/transparent_dark</item>
</style>

Google not helped me.

1

There are 1 answers

0
Кирилл Деревяновский On

By default, the actionbar processes WindowInsets and adds padding where the system elements should be (statusbar, navigationbar and cutout like mine). If you add your actionbar to the layout, you can decide how to handle WindowInsets yourself.

themedAppBarLayout(R.style.MyTheme_Viewer_ActionBarOverlay) {
  id = Id.toolbar
  backgroundColorResource = R.color.transparent_dark

  doOnApplyWindowInstets { v, insets, _ ->
    v.updateLayoutParams<ViewGroup.MarginLayoutParams> {

      // Added indent only on top. 
      // ActionBar takes up the entire width of the screen without indentation.
      topMargin = insets.systemWindowInsetTop

      // If there is a cutout, we get its dimensions
      val cutoutRight = insets.displayCutout?.safeInsetRight ?: 0
      val cutoutLeft = insets.displayCutout?.safeInsetLeft ?: 0
      // Subtract the cutout size from WindowInsets, for fullscreen
      rightMargin = insets.systemWindowInsetRight - cutoutRight
      leftMargin = insets.systemWindowInsetLeft - cutoutLeft
    }
    insets
  }

  toolbar = toolbar {
    lparams(width = matchParent, height = wrapContent)
  }
}


fun View.doOnApplyWindowInstets(block: (View, WindowInsetsCompat, Rect) -> WindowInsetsCompat) {
  val initialPadding = recordInitialPaddingForView(this)

  ViewCompat.setOnApplyWindowInsetsListener(this) { v, insets ->
    block(v, insets, initialPadding)
  }
  doFromSdk(20) {
    requestApplyInsetsWhenAttached()
  }
}


@RequiresApi(Build.VERSION_CODES.KITKAT_WATCH)
fun View.requestApplyInsetsWhenAttached() {
  if (isAttachedToWindow) {
    requestApplyInsets()
  } else {
    addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
      override fun onViewAttachedToWindow(v: View) {
        v.removeOnAttachStateChangeListener(this)
        v.requestApplyInsets()
      }

      override fun onViewDetachedFromWindow(v: View) = Unit
    })
  }
}


fun recordInitialPaddingForView(view: View) =
    Rect(view.paddingLeft, view.paddingTop, view.paddingRight, view.paddingBottom)