Search code examples
androidkotlinlandscape-portraitdevice-orientation

How to add padding to my UI to avoid being obscured by display cut-out when in landscape orientation?


display cut-out screenshot

I still want the bottom navigation bar to remain the same length, but I want to add some padding in the container to the left to shift the cards over to the right a bit. I have the following code in my MainActivity.kt right now:

WindowCompat.setDecorFitsSystemWindows(window, false)
    ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets ->
        val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
        view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
            topMargin = insets.top
        }
        binding.bottomNavigationView.updatePadding(bottom = insets.bottom)
        WindowInsetsCompat.CONSUMED
    }

My activity_main.xml is composed of a ConstraintLayout that encloses two elements: BottomNavigationView and FragmentContainerView.


Solution

  • Fixed it thanks to @Zain's help!

    private var cutoutDepth = 0
    
    override fun onCreate(savedInstanceState: Bundle?) {
        [...]
        ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets ->
            val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
            cutoutDepth = insets.top
            [...]
        }
        [...]
    }
    
    override fun onResume() {
        super.onResume()
        // Starts the orientation listener
        if (orientationListener.canDetectOrientation())
            orientationListener.enable()
    }
    
    override fun onPause() {
        super.onPause()
        // Stops the orientation listener
        orientationListener.disable()
    }
    
    private val orientationListener by lazy {
        object : OrientationEventListener(applicationContext, SensorManager.SENSOR_DELAY_NORMAL) {
            override fun onOrientationChanged(orientation: Int) {
                if (orientation == ORIENTATION_UNKNOWN)
                    return
                when (display?.rotation) {
                    Surface.ROTATION_0 -> {
                        // Bottom - reset the padding in portrait
                        binding.navHostFragmentActivityMain.setPadding(0, 0, 0, 0)
                    }
                    Surface.ROTATION_90 -> {
                        // Left
                        binding.navHostFragmentActivityMain.setPadding(cutoutDepth, 0, 0, 0)
                    }
                    Surface.ROTATION_180 -> {
                        // Top - reset the padding if upside down
                        binding.navHostFragmentActivityMain.setPadding(0, 0, 0, 0)
                    }
                    Surface.ROTATION_270 -> {
                        // Right
                        binding.navHostFragmentActivityMain.setPadding(0, 0, cutoutDepth, 0)
                    }
                }
            }
        }
    }
    

    End result:

    end result