How to get DisplayCutout height when creating an Activity?
Solution 1
There seems to be no way to get WindowInsets
object in onCreate. Your Activity
has to be attached to window first. So your options are:
1.
override fun onAttachedToWindow() {
val cutout = window.decorView.rootWindowInsets.displayCutout
}
2.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
contentView?.setOnApplyWindowInsetsListener { _, insets ->
val cutout = insets.displayCutout
return@setOnApplyWindowInsetsListener insets
}
}
Solution 2
This modification of Roman's answer (above) worked for me:
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
Log.i("Chicken", "cutout: " + getWindow().getDecorView().getRootWindowInsets().getDisplayCutout());
}
Solution 3
WindowInsets.getDisplayCutout()
returns the DisplayCutout
object if present.
To get the bounding rectangle of display cutout you can make use of
DisplayCutout.getBoundingRects()
It will give you a list of Rect
of all the display cutouts(non-functional area) on the screen.
In order to get the height of each display cutout,
Rect.height()
This might return negative values also so make sure to take the modulus of height.
For more information about display cutout support, see the following links:
android:windowLayoutInDisplayCutoutMode
WindowInsets.getDisplayCutout()
Solution 4
Here's how in onCreate():
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
drumRoll1Button.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
DisplayCutout displayCutout = drumRoll1Button.getRootWindowInsets().getDisplayCutout();
if (displayCutout!=null) {
displayCutoutLengthPx = displayCutout.getSafeInsetLeft();
}
Log.v(LOG_TAG,"displayCutoutLengthPx:"+displayCutoutLengthPx);
}
});
}
Please swap in any view on screen (for drumRoll1Button) and getSafeInsetTop() (for getSafeInsetLeft()) if you are in Portrait mode, which the original question is asking. This sample works for Landscape.
luben
Updated on July 19, 2022Comments
-
luben almost 2 years
I have a game with full screen SurfaceView (Portrait) and thread that renders continously on the surface.
The SurfaceView is initialized
onCreate
and its size is determined by the width and height of the screen in pixels.After it's created, it is set as the content view of the Game Activity (no XML definitions):
Bitmap frameBuffer = Bitmap.createBitmap(screenWidth, screenHeight, Config.ARGB_8888); MySurfaceView renderView = new MySurfaceView(this, frameBuffer); this.setContentView(renderView);
The problem is, height of the screen doesn't include Display Cutouts (for devices that have them) and is taller than the allowed drawing screen, because the renderView is placed below the cutout area and does not use it for rendering.
I seek to find the real
screen height - display cutout height
so that I can make the frame buffer have that height.Do you know if there is way to get display cutout area height
onCreate
, the same way we're able to get navigation/status bar height. Below is a snippet that returns navigation bar height:Resources resources = getResources(); int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); if (resourceId > 0) { int navigationBarHeight = resources.getDimensionPixelSize(resourceId); }
Thank you for your help!
--- UPDATE ---
I will try to clarify the question more:
1)
onCreate
a full screen portrait SurfaceView is created with the dimensions of the screen width and height (no XML)2) Immersive mode is enabled for API level > 19 (KitKat)
3) Screen width and height is taken with Display.getSize() or Display.getRealSize() depending on API level
4) On devices with Top Display Cutout the view is automatically placed below the cutout and bottom content is cut out, and this is the issue
5) I would like to get the height of the Display Cutout
onCreate
, so that I can create the SurfaceView height to bescreenHeight - displayCutoutHeight
.6) The problem boils down to finding the height of the Display Cutout.
-
luben over 5 yearsThank you for the answer. I read that I can get it with WindowInsets, but I cannot understand how to get the insets during onCreate. I've read all the links that you posted and all examples show how to do it with listener on the view object: onApplyWindowInsetsListener. The problem is that the view is placed below the insets (cutouts) and the listener always returns zero values for the cutouts, because they are not overlapping the view - they are above it in another window. Can you please provide a code snippet how you would get the insets object? From there I can get the Rect values.
-
user924 over 3 yearsBE CAREFULL if your phone in your hands a little be rotated by some angle during rotation in this method you will get wrong insents