WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) 後,內容區域頂部被狀態欄遮擋。設置 fitsSystemWindows="true 後,View 會在佈局時預留系統窗口 (狀態欄/導航欄) 的內邊距,將內容下移。若根佈局未聲明此屬性,或中間佈局層級阻斷了 WindowInsets 分發,內容就會繪製到狀態欄下方。
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<!-- 子 View 將自動獲得內邊距 -->
</LinearLayout>
View rootView = findViewById(android.R.id.content).getRootView();
ViewCompat.setOnApplyWindowInsetsListener(rootView, (v, insets) -> {
// 僅對特定子 View 應用內邊距
View toolbar = findViewById(R.id.toolbar);
ViewCompat.setPaddingRelative(toolbar,
toolbar.getPaddingStart(),
insets.getSystemWindowInsetTop(), // 狀態欄高度
toolbar.getPaddingEnd(),
toolbar.getPaddingBottom());
return insets.consumeSystemWindowInsets();
});
// 在 Activity onCreate 中
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// 為根佈局設置上邊距 = 狀態欄高度
View contentView = findViewById(android.R.id.content);
contentView.setPadding(0, getStatusBarHeight(), 0, 0);
}
| 誤區 | 正確認知 |
|---|---|
| 只在 Toolbar 加 fitsSystemWindows | 必須在**根佈局**或接收 WindowInsets 的父容器設置 |
| ScrollView/RecyclerView 內部失效 | 確保它們也是 fitsSystemWindows=true,或用 paddingTop 手動預留 |
| 設置后狀態欄顏色變灰 | 需同時設置 window.setStatusBarColor(Color.TRANSPARENT) 配合透明狀態欄 |
adb shell dumpsys window_display 查看 WindowInsets 分發鏈路。