Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get DisplayCutout height when creating an Activity?

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 be screenHeight - displayCutoutHeight.

6) The problem boils down to finding the height of the Display Cutout.

like image 636
luben Avatar asked Sep 05 '18 16:09

luben


People also ask

How do I get a display cutout?

If you're rendering into the cutout area, you can use WindowInsetsCompat. getDisplayCutout() to retrieve a DisplayCutout object that contains the safe insets and bounding box for each cutout. These APIs let you check whether your content overlaps with the cutout so that you can reposition, if needed.

What is double cut out app?

Double screen cutout will put a notch on the leading and the bottom of the gadget, just like the ZTE prototype the company revealed a less than a month earlier. The corner display cutout will cut out a pit of the display in the corner of the mobile phone.


2 Answers

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.

like image 141
TomV Avatar answered Oct 04 '22 06:10

TomV


This modification of Roman's answer (above) worked for me:

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        Log.i("Chicken", "cutout: " + getWindow().getDecorView().getRootWindowInsets().getDisplayCutout());
   }
like image 36
Adam Avatar answered Oct 04 '22 04:10

Adam