Instead of padding the layout the documentation offers the default cutout mode option for that.
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT - With this default setting,
content renders into the cutout area when displayed in portrait mode,
but content is letterboxed when displayed in landscape mode
So, you'd designate that in the themes/style file using:
<item name="android:windowLayoutInDisplayCutoutMode">default</item>
Update
I have it set to shortEdges because I don't want the default behavior. The default behavior doesn't go edge-to-edge when in landscape orientation. The problem I'm having is that the cards get obscured, so I'm wondering how to fix that with either inset margins or padding.
As the place to add padding would would change in terms of the device orientation direction, so you'd track changes in orientation direction with OrientationEventListener
and add the padding accordingly.
The typical value of the cutout depth could be discovered as the max value of the screen insets (because the app would be launched in portrait, landscape left/right); in each case, the cutout position is different.
private var cutoutDepth = 0
WindowCompat.setDecorFitsSystemWindows(window, false)
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
cutoutDepth = Collections.max(listOf(insets.bottom, insets.left, insets.right))
// reset of code is omitted
Notice that the cutoutDepth
variable should be saved in a permanent storage like a ViewModel; you need to handle that.
Here by the padding is added to the root view; but you'd cascade that to the RecyclerView
in the fragment.
private val orientationListener by lazy {
object : OrientationEventListener(applicationContext, SensorManager.SENSOR_DELAY_NORMAL) {
override fun onOrientationChanged(orientation: Int) {
if (orientation == ORIENTATION_UNKNOWN) return
val rotation =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) display?.rotation
else windowManager.defaultDisplay.rotation
when (rotation) {
Surface.ROTATION_0 -> {
// BOTTOM
binding.root.setPadding(0, 0, 0, 0) // reset the padding in portrait
Log.d("LOG_TAG", "Orientation: BOTTOM")
}
Surface.ROTATION_90 -> {
// LEFT
binding.root.setPadding(cutoutDepth, 0, 0, 0)
Log.d("LOG_TAG", "Orientation: LEFT")
}
Surface.ROTATION_180 -> {
// TOP
binding.root.setPadding(0, 0, 0, 0) // // reset the padding in upside down (if it's allowed)
Log.d("LOG_TAG", "Orientation: TOP")
}
Surface.ROTATION_270 -> {
// RIGHT
binding.root.setPadding(0, 0, cutoutDepth, 0)
Log.d("LOG_TAG", "Orientation: RIGHT")
}
}
}
}
}
override fun onResume() {
super.onResume()
// start the orientation listener
if (orientationListener.canDetectOrientation())
orientationListener.enable()
}
override fun onPause() {
super.onPause()
// stop the orientation listener
orientationListener.disable()
}