我正在尝试获取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());
}
答案 0 :(得分:1)
getRootWindowInsets仅在视图分离时才返回null。确保从正确的上下文中调用它。
答案 1 :(得分:1)
public static boolean hasNotchInScreenOfAndroidP(View context) {
final boolean[] ret = {false};
final View view=context;
if (Build.VERSION.SDK_INT >= 28) {
if (context==null){
}else {
context.post(new Runnable() {
@Override
public void run() {
WindowInsets windowInsets=view.getRootWindowInsets();
if (windowInsets==null){
}else {
DisplayCutout displayCutout = view.getRootWindowInsets().getDisplayCutout();
if (displayCutout == null ) {
ret[0] = false;
} else {
List<Rect> rects = displayCutout.getBoundingRects();
if (rects == null || rects.size() == 0) {
ret[0] = false;
} else {
ret[0] = true;
}
}
}
}
});
}
}
return ret[0];
}
ComUtil.getStateBarHeightOfSeparationFromTheTop(this,getWindow()。getDecorView());
答案 2 :(得分:0)
尝试下面的代码。我可以使用 View.OnAttachStateChangeListener 获取状态栏的高度。就我而言,我已将侦听器附加到ScrollView(mDetailScrollView),将其更改为要附加侦听器的任何视图。
...
mDetailScrollView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
DisplayCutout displayCutout = getDisplayCutout();
if (displayCutout != null) {
// your code...
}
}
@Override
public void onViewDetachedFromWindow(View v) {
}
});
...
private DisplayCutout getDisplayCutout() {
if (activity != null) {
WindowInsets windowInsets = getWindow().getDecorView().getRootWindowInsets();
if (windowInsets != null) {
return windowInsets.getDisplayCutout();
}
}
return null;
}
答案 3 :(得分:0)
您可以在处理程序中获取DisplayCutout
val cutoutHandler = HandlerThread("cutout-thread")
cutoutHandler.start()
var handler = object : Handler(cutoutHandler.looper) {
override fun handleMessage(msg: Message?) {
super.handleMessage(msg)
runOnUiThread {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { // 9.0原生
val windowInsets = window.decorView.rootWindowInsets
val displayCutout = windowInsets.displayCutout
}
cutoutHandler.quit()
}
}
}
Thread {
handler.sendEmptyMessage(0)
}.start()
答案 4 :(得分:0)
您应该将代码放在
上@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
DisplayCutout displayCutout;
displayCutout =
getWindow().getDecorView().getRootWindowInsets().getDisplayCutout();
//Logger.e(TAG, "MARGIN " + displayCutout.getSafeInsetTop());
}
}
答案 5 :(得分:0)
这是我在运行模拟器时发生的。看起来,即使您的模拟器具有带有显示切口的默认外观,它仍然可能不会将其注册为显示切口设备。
您可以通过在开发人员选项中启用“模拟带有切口的显示”来解决此问题:
https://developer.android.com/guide/topics/display-cutout/#test_how_your_content_renders
答案 6 :(得分:0)
我必须使用OnApplyWindowInsetsListener
的组合,并从DisplayCutout
获得DecorView
:
public class MyActivity extends AppCompatActivity implements androidx.core.view.OnApplyWindowInsetsListener {
private Rect insets = new Rect();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
//...
ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView(), this);
}
@Override
public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) {
DisplayCutoutCompat cutoutCompat = insets.getDisplayCutout();
if (cutoutCompat != null) {
this.insets.set(cutoutCompat.getSafeInsetLeft(), cutoutCompat.getSafeInsetTop(), cutoutCompat.getSafeInsetRight(), cutoutCompat.getSafeInsetBottom());
} else {
this.insets.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
}
//cutoutCompat is null at this point... So get it the other way.
if (getWindow().getDecorView() != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
WindowInsets rootWindowInsets = getWindow().getDecorView().getRootWindowInsets();
if (rootWindowInsets != null) {
DisplayCutout displayCutout = rootWindowInsets.getDisplayCutout();
if (displayCutout != null) {
this.insets.set(displayCutout.getSafeInsetLeft(), displayCutout.getSafeInsetTop(), displayCutout.getSafeInsetRight(), displayCutout.getSafeInsetBottom());
}
}
}
return insets;
}
}