Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the height of "notch" so contents won't be cut off

How can I get the height of recent android phones' notch, preferably in pixels?

I have an implementation where an image MUST be at the top in full screen.

With the addition of a notch to recently released phones, this image will be cut out by the notch. My idea is to get the notch height and add a margin above it dynamically to accommodate different notch sizes.

Any help or other approaches would be greatly appreciated.

like image 478
memelord9001 Avatar asked Oct 18 '25 21:10

memelord9001


2 Answers

The easiest way to get the cutout's height in pixels is to override onAttachedToWindow() function of your View. View being attached to window is the main requirement to rootWindowInsets being non-null. Note that it's safe to check SDK version, because complete support of cutout has been started since Android Pie.

override fun onAttachedToWindow() {
     super.onAttachedToWindow()
     layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT).apply {
           topMargin = 
               if (SDK_INT >= Build.VERSION_CODES.P) rootWindowInsets?.displayCutout?.safeInsetTop ?: 0 
               else 0 
     }

}

In case that your View isn't CustomView you should add OnAttachStateChangeListener:

imageView.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
     override fun onViewDetachedFromWindow(v: View?) { }

     override fun onViewAttachedToWindow(v: View?) {
         // call the code from above starting from 'layoutParams = ...' on your View object
     }
})

Don't forget to change LayoutParams(MATCH_PARENT, WRAP_CONTENT) for your own needs.

like image 159
aspix Avatar answered Oct 20 '25 11:10

aspix


I used the method below(in Kotlin):

*It will only work in Android P and above.

*My activity is a full screen activity.

*My assumption is android phone with notches are relatively new will either come out of the box with Android P or have been rapidly updated to Android P.

Create a OnGlobalLayoutListener

private val onDisplayCutoutReadyListener : ViewTreeObserver.OnGlobalLayoutListener = ViewTreeObserver.OnGlobalLayoutListener{
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {

        var displayCutout = window.decorView.rootWindowInsets.displayCutout
        if (displayCutout.boundingRects.size>0) {
            val notchRect = displayCutout.boundingRects.get(0)
            Log.v(TAG,"notch height in pixels="+notchRect.height())
        }
    }

}

Add the listener to your activity's rootview using .viewTreeObserver.addOnGlobalLayoutListener()

layout_fullscreen.viewTreeObserver.addOnGlobalLayoutListener(onDisplayCutoutReadyListener)

My layout xml where layout_fullscreen is the rootview.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_fullscreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_weight="1"
    android:layout_height="0dp">
    <com.baidu.mapapi.map.MapView
        android:id="@+id/map_location"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

like image 24
ChinLoong Avatar answered Oct 20 '25 09:10

ChinLoong



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!