我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
}
}
问题
一旦附加到视图层次结构中,如何随时从代码中的任何位置可靠地获取显示切口?
重现问题
经过大量调查后,我将其缩小为全屏应用程序的一个非常广泛的问题,我很惊讶没有其他人询问它。事实上,我们可以忽略我的应用程序,只处理两个您现在可以自己制作的模板项目。
在 Android 工作室中,我正在谈论称为“基本活动”和“全屏活动”的手机和平板电脑项目。如果您创建其中一个,并进行以下更改:
对于 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">
现在对于他们两个,将以下两个函数添加到活动文件中:
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
WindowInsets insets = getWindow().getDecorView().getRootWindowInsets();
if (insets != null) {
DisplayCutout displayCutout = insets.getDisplayCutout();
if (displayCutout != null && displayCutout.getBoundingRects().size() > 0) {
// we have cutouts to deal with
}
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
WindowInsets insets = getWindow().getDecorView().getRootWindowInsets();
if (insets != null) {
DisplayCutout displayCutout = insets.getDisplayCutout();
if (displayCutout != null && displayCutout.getBoundingRects().size() > 0) {
// we have cutouts to deal with
}
}
}
这就是重现此问题所需要做的一切。我在 API Q 上的 Pixel 3 模拟器上运行它,在该模拟器上我启用了模拟切口并选择了 BOTH(所以底部和顶部都有一个切口)
现在,如果您在我们尝试获取显示切口 ( DisplayCutout displayCutout = insets.getDisplayCutout();
) 的行上设置断点,您将在 Basic 应用程序中看到它在启动和更改方向时有效,但在全屏应用程序中它仅在启动时有效。
事实上,在我的应用程序中,我已经使用以下代码进行了测试onAttachedToWindow
:
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
// start a thread so that UI thread execution can continue
WorkerThreadManager.StartWork(new WorkerCallback() {
@Override
public void StartWorkSafe() {
// run the following code on the UI thread
XPlatUtil.RunOnUiThread(new SafeRunnable() {
public synchronized void RunSafe() {
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
}
}
}
});
}
});
}
此代码启动一个线程,以便 onAttachedToWindow 函数可以完成运行;但线程立即将执行发送回 UI 线程以检查切口。
onAttachedToWindow 函数完成其执行与我的代码检查 displayCutout 之间的延迟必须在纳秒级,但切口立即不可用。
有任何想法吗?这是以某种方式预期的吗?
当方向改变时无法访问切口我别无选择,只能记录最大的插图(纵向的顶部或底部,因为长边不能有它们),并将其应用于纵向的顶部和底部,或左侧和右侧在景观中。
这是因为我无法在 android 中找到一种方法来检查当前处于活动状态的哪种景观(例如,手机顶部是左侧还是右侧)。如果我能检查一下,我至少可以只在手机边缘需要它的地方应用插图。