Как получить высоту DisplayCutout при создании деятельности?
У меня есть игра с полноэкранным режимом 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) Ширина и высота экрана берется с помощью Display.getSize() или Display.getRealSize() в зависимости от уровня API
4) На устройствах с верхним вырезом дисплея вид автоматически размещается под вырезом, а нижнее содержимое вырезается, и это проблема
5) Хотелось бы получить высоту выреза дисплея onCreate
, так что я могу создать высоту SurfaceView, чтобы быть screenHeight - displayCutoutHeight
,
6) Проблема сводится к поиску высоты выреза дисплея.
2 ответа
Кажется, нет никакого способа получить WindowInsets
объект в onCreate. Ваш 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()
Это может также вернуть отрицательные значения, поэтому убедитесь, что вы взяли модуль высоты.
Для получения дополнительной информации о поддержке вырезов на экране см. Следующие ссылки:
Эта модификация ответа Романа (выше) сработала для меня:
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
Log.i("Chicken", "cutout: " + getWindow().getDecorView().getRootWindowInsets().getDisplayCutout());
}
Вот как это сделать в 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()), если вы находитесь в портретном режиме, который задается в исходном вопросе. Этот образец работает для ландшафта.
Прекратите читать частные ресурсы Android и перестаньте вызывать getRealSize(). Просто вызовите getSize(), и значения, которые вы получите, будут полезны.