全画面 SurfaceView (Portrait)と、表面上で継続的にレンダリングするスレッドを備えたゲームがあります。
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)画面の幅と高さは、APIレベルに応じてDisplay.getSize()またはDisplay.getRealSize()で取得されます
4)上部ディスプレイカットアウトを備えたデバイスでは、ビューがカットアウトの下に自動的に配置され、下部のコンテンツがカットアウトされます。これが問題です
5)表示カットアウトonCreate
の高さを取得したいので、SurfaceViewの高さをscreenHeight - displayCutoutHeight
。
6)問題は、ディスプレイカットアウトの高さを見つけることです。
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
}
}
WindowInsets.getDisplayCutout()
は、DisplayCutout
オブジェクトを返します(存在する場合)。
表示カットアウトの境界矩形を取得するには、次を使用できます。
DisplayCutout.getBoundingRects()
画面上のすべての表示カットアウト(非機能領域)のRect
のリストが表示されます。
各ディスプレイの切り欠きの高さを取得するには、
Rect.height()
これも負の値を返す可能性があるため、高さの係数を必ず取得してください。
ディスプレイのカットアウトサポートの詳細については、次のリンクを参照してください。
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()の場合)を交換してください。このサンプルは、Landscapeで機能します。
読み取りの停止AndroidプライベートリソースとgetRealSize()の呼び出しを停止します。getSize()を呼び出すだけで、取得した値を使用できます。