系統資訊列保護功能

應用程式指定目標為 SDK 35 以上版本後,系統會強制執行無邊框設計。系統狀態列和手勢導覽列為透明,但三按鈕導覽列則為半透明。呼叫 enableEdgeToEdge 即可讓此功能向下相容。

不過,系統預設值可能不適用於所有用途。請參閱 Android 系統列設計指南邊到邊設計指南,瞭解何時應考慮使用透明或半透明的系統列。

建立透明的系統列

指定 Android 15 以上版本,或呼叫 enableEdgeToEdge() 並使用早期版本的預設引數,即可建立透明手勢導覽列。針對三按鈕導覽列,請將 Window.setNavigationBarContrastEnforced 設為 false,否則系統會套用半透明遮罩。

建立半透明的系統列

如要建立半透明狀態列,請建立可重疊主要內容的自訂可組合函式,並在內嵌區域所涵蓋的區域中繪製漸層。

class SystemBarProtectionSnippets : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // enableEdgeToEdge sets window.isNavigationBarContrastEnforced = true
        // which is used to add a translucent scrim to three-button navigation
        enableEdgeToEdge()

        setContent {
            MyTheme {
                // Main content
                MyContent()

                // After drawing main content, draw status bar protection
                StatusBarProtection()
            }
        }
    }
}

@Composable
private fun StatusBarProtection(
    color: Color = MaterialTheme.colorScheme.surfaceContainer,
    heightProvider: () -> Float = calculateGradientHeight(),
) {

    Canvas(Modifier.fillMaxSize()) {
        val calculatedHeight = heightProvider()
        val gradient = Brush.verticalGradient(
            colors = listOf(
                color.copy(alpha = 1f),
                color.copy(alpha = .8f),
                Color.Transparent
            ),
            startY = 0f,
            endY = calculatedHeight
        )
        drawRect(
            brush = gradient,
            size = Size(size.width, calculatedHeight),
        )
    }
}

@Composable
fun calculateGradientHeight(): () -> Float {
    val statusBars = WindowInsets.statusBars
    val density = LocalDensity.current
    return { statusBars.getTop(density).times(1.2f) }
}

圖 1. 半透明狀態列。

如果是自適應應用程式,請插入與各個窗格顏色相符的自訂可組合項,如無邊框設計所示。如要建立半透明的導覽列,請將 Window.setNavigationBarContrastEnforced 設為 true。