我有一个全屏幕SurfaceView(肖像)游戏和在表面上连续渲染的线程.
SurfaceView已初始化onCreate,其大小由屏幕的宽度和高度(以像素为单位)决定.
创建后,将其设置为游戏活动的内容视图(无XML定义):
Bitmap frameBuffer = Bitmap.createBitmap(screenWidth, screenHeight, Config.ARGB_8888);
MySurfaceView renderView = new MySurfaceView(this, frameBuffer);
this.setContentView(renderView);
Run Code Online (Sandbox Code Playgroud)
问题是,屏幕的高度不包括显示切口(对于具有它们的设备)并且比允许的绘图屏幕高,因为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);
}
Run Code Online (Sandbox Code Playgroud)
谢谢您的帮助!
---更新---
我会尝试更多地澄清这个问题:
1)onCreate使用屏幕宽度和高度(无XML)创建全屏肖像SurfaceView
2)API级别> 19(KitKat)启用沉浸模式
3)屏幕宽度和高度采用Display.getSize()或Display.getRealSize()取决于API级别
4)在具有顶部显示切口的设备上,视图自动放置在切口下方,底部内容被剪切掉,这就是问题所在
5)我想获得Display Cutout的高度onCreate,以便我可以创建SurfaceView高度screenHeight - displayCutoutHeight.
6)问题归结为找到显示切口的高度.
android surfaceview android-layout android-9.0-pie display-cutouts
我正在尝试获得 DisplayCutout 并获得一个
java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“android.view.DisplayCutout android.view.WindowInsets.getDisplayCutout()”
这是我的代码:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
DisplayCutout displayCutout;
displayCutout = getWindow().getDecorView().getRootWindowInsets().getDisplayCutout();
//Logger.e(TAG, "MARGIN " + displayCutout.getSafeInsetTop());
}
Run Code Online (Sandbox Code Playgroud) 使用viewport-fit=cover. Safari 将内容全屏拉伸到切口区域,而 Chrome 则没有(请参见下面华为 Y6 的屏幕截图)这是 Android 上的标准行为还是向 Safari 之类行为的过渡阶段?
在 iPhoneX 上,下面的代码使内容边缘到边缘也延伸到切口区域。然后,您通过使用 CSS 安全区域常量来应用边距、填充等来补偿“吃”到实际内容中的缺口:
<meta name="viewport" content="width=device-width, viewport-fit=cover">
<style>
body {
padding-top: env(safe-area-inset-top);
}
</style>
Run Code Online (Sandbox Code Playgroud)
在 Adroid 9 Pie 上的最新 Chrome 上,凹口旁边的“角”区域(实际切口)始终是“安全的”,并且具有浏览器 chrome 的默认背景颜色(灰白色)或您在其中定义的任何颜色该<meta name="theme-color">标签。CSS 安全区常量什么都不做,因为...没有什么可以防范的。
我正在创建一个 Android 应用程序,其中使用服务和窗口管理器在所有应用程序之上显示浮动视图。我正在尝试在窗口管理器参数中添加 WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 以使我的布局能够与显示切口重叠。但这似乎不适用于我的情况。
我已经尝试过以两种方式添加它:
通过使用 XML 样式:
<style name="OverlayTheme">
<item name="android:windowLayoutInDisplayCutoutMode">
shortEdges <!-- default, shortEdges, never -->
</item>
</style>
Run Code Online (Sandbox Code Playgroud)
并在我的布局根视图中添加了此样式。但这不起作用。
通过在我的服务中使用 JAVA 代码:
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT);
Run Code Online (Sandbox Code Playgroud)
它也不起作用。我不确定我是否正确应用了布局参数。请帮我找出问题所在。提前致谢。
编辑:
这是我在服务中实现气泡的方式:
在 onCreate() 方法中初始化窗口管理器和布局:
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (inflater != null) mLayout = inflater.inflate(R.layout.my_layout, null, false);
Run Code Online (Sandbox Code Playgroud)通过窗口管理器将此视图添加到窗口:
WindowManager.LayoutParams params;
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSLUCENT);
Run Code Online (Sandbox Code Playgroud)最后通过 addView …
android android-service android-layout android-windowmanager display-cutouts
我正在使用 Android Studio 模板“ Navigation Drawer Activity ”开发 Android 应用程序,但是如果我在带有 Notch/display Cutouts 的手机上打开导航抽屉,更大的状态栏会覆盖 Navigation Drawer header 的顶部。
我怎么能解决这个问题?
这是活动布局xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start"
android:background="@color/colorPrimaryDark">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
Run Code Online (Sandbox Code Playgroud)
和导航抽屉标题布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="@dimen/nav_header_height"
android:background="@drawable/navbar_size_edit"
android:gravity="bottom"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin_bar_bottom"
android:paddingLeft="@dimen/activity_horizontal_margin_bar"
android:paddingRight="@dimen/activity_horizontal_margin_bar"
android:paddingTop="@dimen/activity_vertical_margin_bar"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/nav_header_desc"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:paddingBottom="@dimen/activity_vertical_margin_bar_bottom"
app:srcCompat="@mipmap/avatar_me_round" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:text="@string/app_name"
android:textStyle="bold"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" /> …Run Code Online (Sandbox Code Playgroud) 我有一个全屏的cordova应用程序,我以前使用下面的css来显示iPhone X的缺口,
padding-top: 25px;
padding-top: env(safe-area-inset-top);
Run Code Online (Sandbox Code Playgroud)
并且Android会忽略env(safe-area-inset-top),并使用25px来防止状态栏覆盖我的视图。
就是这样,我env()在Android Oreo手机(华为mate10)中将Android系统Webview组件升级到版本69.0.3497.100后,突然发现对Webview的支持。
但是,当我在Android Pie仿真器中安装此cordova应用程序时(启用了抠图仿真并安装了Chrome / Webview 69),我发现它env(safe-area-inset-top)为0px,根本没有填充顶部。
抠图区域/状态栏覆盖了我的Web内容:
Chrome / Webview 69是否支持safe-area-inset-top?
getDisplayCutout()我的全屏 Java 应用程序有问题。我似乎只能在onAttachedToWindow函数中获取 DisplayCutout 的值。该功能完成后,我再也无法获得它。获取切口的代码:
WindowInsets insets = myActivity.getWindow().getDecorView().getRootWindowInsets();
if (insets != null) {
DisplayCutout displayCutout = insets.getDisplayCutout();
if (displayCutout != null && displayCutout.getBoundingRects().size() > 0) {
// we have cutouts to deal with
}
}
Run Code Online (Sandbox Code Playgroud)
一旦附加到视图层次结构,如何从代码中的任何位置可靠地获取显示切口?
经过大量调查,我将其范围缩小到全屏应用程序的一个非常广泛的问题,我很惊讶没有其他人询问它。事实上,我们可以忽略我的应用程序,只需处理两个模板项目,您现在就可以自己制作。
在 Android Studio 中,我谈论的是名为“基本活动”和“全屏活动”的手机和平板电脑项目。如果您创建其中之一,并进行以下更改:
对于 Basic,更改 Manifest 以通过android:configChanges="orientation|keyboardHidden|screenSize"在 Activity 标签下添加自己来处理配置更改,如下所示:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@style/AppTheme.NoActionBar">
Run Code Online (Sandbox Code Playgroud)
现在,将以下两个函数添加到活动文件中:
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
WindowInsets insets = getWindow().getDecorView().getRootWindowInsets();
if (insets != null) {
DisplayCutout displayCutout = insets.getDisplayCutout(); …Run Code Online (Sandbox Code Playgroud) 在我的活动中,我使用以下代码打开/关闭全屏。我所说的全屏是指隐藏/显示状态栏。该问题发生在具有切口(有摄像头的地方)且状态栏可见且处于横向状态的设备上。当状态栏隐藏或/和处于纵向时它会延伸。
if(aStatus){ // Hide
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN , WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
Run Code Online (Sandbox Code Playgroud)
如图所示,左侧的白色区域应被覆盖。
https://i.stack.imgur.com/7va88.png
compileSdkVersion 29
buildToolsVersion '29.0.3'
minSdkVersion 21
targetSdkVersion 29
Run Code Online (Sandbox Code Playgroud)
所选解决方案将获得 50 积分奖励。谢谢你!