我有一个全屏SurfaceView(纵向)的游戏,线程在表面连续渲染。
SurfaceView已初始化onCreate
,其大小由屏幕的宽度和高度(以像素为单位)确定。
创建后,将其设置为游戏活动的内容视图(无XML定义):
Bitmap frameBuffer = Bitmap.createBitmap(screenWidth, screenHeight, Config.ARGB_8888);
MySurfaceView renderView = new MySurfaceView(this, frameBuffer);
this.setContentView(renderView);
问题是,屏幕高度不包括“显示切口”(对于具有它们的设备),并且比允许的绘制屏幕高,这是因为renderView放置在切口区域下方,并且不使用它进行渲染。
我试图找到真实的screen height - display cutout height
,以便使帧缓冲区具有该高度。
您是否知道是否可以获取显示切口区域高度onCreate
,就像我们能够获取导航/状态栏高度一样。以下是返回导航栏高度的代码段:
Resources resources = getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
int navigationBarHeight = resources.getDimensionPixelSize(resourceId);
}
谢谢您的帮助!
---更新---
我将尝试进一步阐明问题:
1)onCreate
创建了一个全屏肖像SurfaceView,其尺寸为屏幕的宽度和高度(无XML)
2)为API级别> 19(KitKat)启用了沉浸模式
3)屏幕宽度和高度由Display.getSize()或Display.getRealSize()决定,具体取决于API级别
4)在具有顶部显示切口的设备上,视图自动置于切口下方,底部内容被切除,这就是问题
5)我想获取显示切口onCreate
的高度,以便可以将SurfaceView的高度创建为screenHeight - displayCutoutHeight
。
6)问题归结为找到显示切口的高度。
答案 0 :(得分:2)
WindowInsets.getDisplayCutout()
返回DisplayCutout
对象(如果存在)。
要获取显示切口的边界矩形,可以使用
DisplayCutout.getBoundingRects()
它将为您提供屏幕上所有显示切口(非功能区域)的Rect
列表。
为了获得每个显示切口的高度,
Rect.height()
这也可能返回负值,因此请确保采用高度模量。
有关显示抠图支持的更多信息,请参见以下链接:
答案 1 :(得分:2)
似乎无法在onCreate中获取WindowInsets
对象。您的Activity
必须先附加到窗口。因此,您的选择是:
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
}
}
答案 2 :(得分:1)
这是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);
}
});
}
如果您处于纵向模式(原始问题正在询问),请交换屏幕上的任何视图(对于drumRoll1Button)和getSafeInsetTop()(对于getSafeInsetLeft())。此示例适用于风景。
答案 3 :(得分:1)
对Roman答案的修改(上面)对我有用:
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
Log.i("Chicken", "cutout: " + getWindow().getDecorView().getRootWindowInsets().getDisplayCutout());
}
答案 4 :(得分:0)
停止读取Android私有资源,并停止调用getRealSize()。只需调用getSize(),您返回的值将很好使用。