[英]NULL Window Insets
我正在嘗試獲得 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());
}
你應該把你的代碼放在
@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());
}
}
當且僅當視圖分離時,getRootWindowInsets 返回 null。 確保您從正確的上下文中調用它。
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());
試試下面的代碼。 我能夠使用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;
}
您可以在處理程序中獲得 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()
這是我在運行模擬器時發生的。 看起來即使您有一個帶有顯示切口的默認皮膚的模擬器,它仍然可能不會將其注冊為顯示切口設備。
您可以通過在開發人員選項中啟用“模擬帶有切口的顯示”來解決此問題:
https://developer.android.com/guide/topics/display-cutout/#test_how_your_content_renders
我不得不使用OnApplyWindowInsetsListener
的組合並從DecorView
獲取DisplayCutout
:
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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.