为何statusBarBackground始终为null?如何获取StatusBar视图?DrawerLayout是否影响?
Hey there! Let's break down why you're getting null for the status bar view, and whether using DrawerLayout as your root layout plays a role here.
Why Are You Getting Null?
The most common culprit is trying to fetch the view too early. If you call getWindow().getDecorView().findViewById(android.R.id.statusBarBackground) in onCreate(), onStart(), or even early in onResume(), the DecorView hasn't finished initializing yet—so the statusBarBackground view hasn't been added to the view tree, hence the null result.
Another thing to check: if your Activity is in fullscreen mode or has the StatusBar hidden entirely, this view won't exist at all, so returning null is expected behavior.
Correct Ways to Fetch StatusBarBackground
You need to wait until the view hierarchy is fully drawn. Here are two reliable approaches:
1. Use ViewTreeObserver to Listen for Layout Completion
This lets you trigger the fetch right after the view tree is laid out:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_activity_layout); View decorView = getWindow().getDecorView(); decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // Remove the listener to avoid repeated calls if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { decorView.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { // For older SDKs decorView.getViewTreeObserver().removeGlobalOnLayoutListener(this); } View statusBarBackground = decorView.findViewById(android.R.id.statusBarBackground); if (statusBarBackground != null) { // Now you can use this view for shared element transitions! } } }); }
2. Fetch in onWindowFocusChanged()
When the Activity gains window focus, the entire view hierarchy is guaranteed to be ready:
@Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { View statusBarBackground = getWindow().getDecorView().findViewById(android.R.id.statusBarBackground); if (statusBarBackground != null) { // Handle your shared element logic here } } }
Does DrawerLayout as Root Layout Affect This?
No, not directly. The statusBarBackground view is part of the Window's DecorView, which sits above your Activity's root layout (whether it's DrawerLayout, ConstraintLayout, etc.). A few things to note though:
- If you've set
fitsSystemWindows="true"on your DrawerLayout, it will adjust its own padding to account for the StatusBar, but this doesn't affect the existence of the statusBarBackground view. - As long as the StatusBar is visible and you fetch the view at the right time, DrawerLayout won't cause it to be null.
Quick Additional Checks
- Make sure your
targetSdkVersionis at least 21—android.R.id.statusBarBackgroundwas introduced in API 21, so it won't exist on older versions. - Verify your app's theme isn't setting the StatusBar to be fully transparent or hidden (e.g., with
android:statusBarColor="@android:color/transparent"without proper window flags—this might make the view invisible or gone).
内容的提问来源于stack exchange,提问作者bojan

