edge-to-edge

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Prerequisites

前提条件

  • Project MUST use Android Jetpack Compose.
  • Project MUST target SDK 35 or later. If the SDK is lower than 35, increase the SDK to 35.
  • 项目必须使用Android Jetpack Compose。
  • 项目必须以SDK 35或更高版本为目标。如果SDK版本低于35,请将其升级到35。

Step 1: plan

步骤1:规划

  1. Locate and analyze all Activity classes to detect which have existing edge-to-edge support. For every Activity without edge-to-edge, plan to make each Activity edge-to-edge.
  2. In each Activity, Locate and analyze all lists and FAB components to detect which have existing edge-to-edge support. For every component without edge-to-edge support, plan to make each of these components edge-to-edge.
  3. In each Activity, scan for
    TextField
    ,
    OutlinedTextField
    , or
    BasicTextField
    . If found, then you MUST verify the IME doesn't hide the input field by following the IME section of this skill.
  1. 定位并分析所有Activity类,检测哪些已支持边缘到边缘显示。对于每个未支持边缘到边缘的Activity,规划为其添加该支持。
  2. 在每个Activity中,定位并分析所有列表和FAB组件,检测哪些已支持边缘到边缘显示。对于每个未支持的组件,规划为其添加该支持。
  3. 在每个Activity中,扫描
    TextField
    OutlinedTextField
    BasicTextField
    。如果找到这些组件,必须按照本技能中关于IME的部分验证输入法不会遮挡输入框。

Step 2: add edge-to-edge support

步骤2:添加边缘到边缘支持

  1. Add
    enableEdgeToEdge
    before
    setContent
    in
    onCreate
    in each Activity that does not already call
    enableEdgeToEdge
    .
  2. Add
    android:windowSoftInputMode="adjustResize"
    in the AndroidManifest.xml for all Activities that use a soft keyboard.
  1. 在每个尚未调用
    enableEdgeToEdge
    的Activity的
    onCreate
    方法中,在
    setContent
    之前添加
    enableEdgeToEdge
  2. 在AndroidManifest.xml中,为所有使用软键盘的Activity添加
    android:windowSoftInputMode="adjustResize"

Step 3: apply insets

步骤3:应用内边距

  • The app MUST apply system insets, or align content to rulers, so critical UI remains tappable. Choose only one method to avoid double padding:
    1. PREFERRED: When available, use
      Scaffold
      s and pass
      PaddingValues
      to the content lambda.
    kotlin
    Scaffold { innerPadding ->
        // innerPadding accounts for system bars and any Scaffold components
        LazyColumn(
            modifier = Modifier
                .fillMaxSize()
                .consumeWindowInsets(innerPadding),
            contentPadding = innerPadding
        ) { /* Content */ }
    }
    <br />
    1. PREFERRED: When available, use the automatic inset handling or padding modifiers in material components.
      • Material 3 Components manages safe areas for its own components, including:
        • TopAppBar
        • SmallTopAppBar
        • CenterAlignedTopAppBar
        • MediumTopAppBar
        • LargeTopAppBar
        • BottomAppBar
        • ModalDrawerSheet
        • DismissibleDrawerSheet
        • PermanentDrawerSheet
        • ModalBottomSheet
        • NavigationBar
        • NavigationRail
      • For Material 2 Components, use the
        windowInsets
        parameter to apply insets manually for
        BottomAppBar
        ,
        TopAppBar
        and
        BottomNavigation
        . DO NOT apply padding to the parent container; instead, pass insets directly to the App Bar component. Applying padding to the parent container prevents the App Bar background from drawing into the system bar area. For example, for
        TopAppBar
        , choose only one of the following options:
        1. PREFERRED:
          TopAppBar(windowInsets = AppBarDefaults.topAppBarWindowInsets)
        2. TopAppBar(windowInsets = WindowInsets.systemBars.exclude(WindowInsets.navigationBars))
        3. TopAppBar(windowInsets = WindowInsets.systemBars.add(WindowInsets.captionBar))
    2. For components outside a Scaffold, use padding modifiers, such as
      Modifier.safeDrawingPadding()
      or
      Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
      .
      kotlin
      Box(
          modifier = Modifier
              .fillMaxSize()
              .safeDrawingPadding()
      ) {
          Button(
              onClick = {},
              modifier = Modifier.align(Alignment.BottomCenter)
          ) {
              Text("Login")
          }
      }
      <br />
    3. For deeply nested components with excessive padding, use
      WindowInsetsRulers
      (e.g.
      Modifier.fitInside(WindowInsetsRulers.SafeDrawing.current)
      ). See the IME section for a code sample.
    4. When you need an element (e.g. a custom header or decorative scrim) to equal the dimensions of a system bar, use inset size modifiers (e.g.
      Modifier.windowInsetsTopHeight(WindowInsets.systemBars)
      ). See the Lists section for a code sample.
  • 应用必须应用系统内边距,或让内容对齐参考线,以确保关键UI保持可点击状态。请仅选择一种方法以避免重复内边距:
    1. 推荐方案: 当可用时,使用
      Scaffold
      并将
      PaddingValues
      传递给内容lambda。
    kotlin
    Scaffold { innerPadding ->
        // innerPadding包含系统栏和所有Scaffold组件的内边距
        LazyColumn(
            modifier = Modifier
                .fillMaxSize()
                .consumeWindowInsets(innerPadding),
            contentPadding = innerPadding
        ) { /* Content */ }
    }
    <br />
    1. 推荐方案: 当可用时,使用Material组件中的自动内边距处理或内边距修饰符。
      • Material 3组件会自行处理自身组件的安全区域,包括:
        • TopAppBar
        • SmallTopAppBar
        • CenterAlignedTopAppBar
        • MediumTopAppBar
        • LargeTopAppBar
        • BottomAppBar
        • ModalDrawerSheet
        • DismissibleDrawerSheet
        • PermanentDrawerSheet
        • ModalBottomSheet
        • NavigationBar
        • NavigationRail
      • 对于Material 2组件,请使用
        windowInsets
        参数为
        BottomAppBar
        TopAppBar
        BottomNavigation
        手动应用内边距。不要为父容器添加内边距;请直接将内边距传递给App Bar组件。为父容器添加内边距会阻止App Bar背景绘制到系统栏区域。例如,对于
        TopAppBar
        ,请仅选择以下选项之一:
        1. 推荐方案:
          TopAppBar(windowInsets = AppBarDefaults.topAppBarWindowInsets)
        2. TopAppBar(windowInsets = WindowInsets.systemBars.exclude(WindowInsets.navigationBars))
        3. TopAppBar(windowInsets = WindowInsets.systemBars.add(WindowInsets.captionBar))
    2. 对于Scaffold之外的组件,使用内边距修饰符,如
      Modifier.safeDrawingPadding()
      Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
      kotlin
      Box(
          modifier = Modifier
              .fillMaxSize()
              .safeDrawingPadding()
      ) {
          Button(
              onClick = {},
              modifier = Modifier.align(Alignment.BottomCenter)
          ) {
              Text("Login")
          }
      }
      <br />
    3. 对于内边距过大的深层嵌套组件,使用
      WindowInsetsRulers
      (例如
      Modifier.fitInside(WindowInsetsRulers.SafeDrawing.current)
      )。请查看IME部分的代码示例。
    4. 当你需要某个元素(如自定义标题栏或装饰性遮罩)与系统栏尺寸相同时,使用内边距尺寸修饰符(例如
      Modifier.windowInsetsTopHeight(WindowInsets.systemBars)
      )。请查看列表部分的代码示例。

Adaptive Scaffolds

自适应Scaffold

  • NavigationSuiteScaffold
    manages safe areas for its own components, like the
    NavigationRail
    or
    NavigationBar
    . However, the adaptive scaffolds (e.g.
    NavigationSuiteScaffold
    ,
    ListDetailPaneScaffold
    ) don't propagate PaddingValues to their inner contents. You MUST apply insets to individual screens or components (e.g., list
    contentPadding
    or FAB padding) as described in Step 3 . DO NOT apply
    safeDrawingPadding
    or similar modifiers to the
    NavigationSuiteScaffold
    parent. This clips and prevents an edge-to-edge screen.
  • NavigationSuiteScaffold
    会自行处理其组件的安全区域,如
    NavigationRail
    NavigationBar
    。但自适应Scaffold(如
    NavigationSuiteScaffold
    ListDetailPaneScaffold
    )不会将PaddingValues传递给其内部内容。你必须按照步骤3中的描述,为单个屏幕或组件(如列表的
    contentPadding
    或FAB内边距)应用内边距。不要
    NavigationSuiteScaffold
    的父容器应用
    safeDrawingPadding
    或类似修饰符,这会裁剪内容并阻止边缘到边缘的全屏显示。

IME

输入法(IME)

  • For each Activity with a soft keyboard, check that
    android:windowSoftInputMode="adjustResize"
    is set in the AndroidManifest.xml. DO NOT use
    SOFT_INPUT_ADJUST_RESIZE
    because it is deprecated. Then, maintain focus on the input field. Choose one:
      1. PREFERRED: Add
        Modifier.fitInside(WindowInsetsRulers.Ime.current)
        to the content container. This is preferred over
        imePadding()
        because it reduces jank and extra padding caused by forgetting to consume insets upstream in the hierarchy.
      1. Add
        imePadding
        to the content container. The padding modifier MUST be placed before
        Modifier.verticalScroll()
        . Do NOT use
        Modifier.imePadding()
        if the parent already accounts for the IME with
        contentWindowInsets
        (e.g.
        contentWindowInsets = WindowInsets.safeDrawing
        ). Doing so will cause double padding.
  • 对于每个使用软键盘的Activity,请检查AndroidManifest.xml中是否设置了
    android:windowSoftInputMode="adjustResize"
    。请勿使用
    SOFT_INPUT_ADJUST_RESIZE
    ,因为它已被废弃。然后,保持输入框的焦点。请选择以下方案之一:
      1. 推荐方案: 为内容容器添加
        Modifier.fitInside(WindowInsetsRulers.Ime.current)
        。相比
        imePadding()
        ,该方案更优,因为它能减少因忘记在层级上游消费内边距而导致的卡顿和多余内边距。
      1. 为内容容器添加
        imePadding
        。该内边距修饰符必须放在
        Modifier.verticalScroll()
        之前。如果父容器已通过
        contentWindowInsets
        (例如
        contentWindowInsets = WindowInsets.safeDrawing
        )处理了IME内边距,则请勿使用
        Modifier.imePadding()
        ,否则会导致重复内边距。

IMEs with Scaffolds code patterns

结合Scaffold的IME代码规范

RIGHT

正确示例

RIGHT because
contentWindowInsets
contains IME insets, which are passed to the content lambda as
innerPadding
.
kotlin
// RIGHT
Scaffold(contentWindowInsets = WindowInsets.safeDrawing) { innerPadding ->
    Column(
        modifier = Modifier
            .padding(innerPadding)
            .consumeWindowInsets(innerPadding)
            .verticalScroll(rememberScrollState())
    ) { /* Content */ }
}
<br />
RIGHT because
fitInside
fits the content to the IME insets regardless of
contentWindowInsets
.
kotlin
// RIGHT
Scaffold() { innerPadding ->
    Column(
        modifier = Modifier
            .padding(innerPadding)
            .consumeWindowInsets(innerPadding)
            .fitInside(WindowInsetsRulers.Ime.current)
            .verticalScroll(rememberScrollState())
    ) { /* Content */ }
}
<br />
RIGHT because the default
contentWindowInsets
does not contain IME insets, and
imePadding()
applies IME insets:
kotlin
// RIGHT
Scaffold() { innerPadding ->
    Column(
        modifier = Modifier
            .padding(innerPadding)
            .consumeWindowInsets(innerPadding)
            .imePadding()
            .verticalScroll(rememberScrollState())
    ) { /* Content */ }
}
<br />
以下示例正确,因为
contentWindowInsets
包含IME内边距,这些内边距会作为
innerPadding
传递给内容lambda。
kotlin
// RIGHT
Scaffold(contentWindowInsets = WindowInsets.safeDrawing) { innerPadding ->
    Column(
        modifier = Modifier
            .padding(innerPadding)
            .consumeWindowInsets(innerPadding)
            .verticalScroll(rememberScrollState())
    ) { /* Content */ }
}
<br />
以下示例正确,因为无论
contentWindowInsets
如何设置,
fitInside
都会让内容适配IME内边距。
kotlin
// RIGHT
Scaffold() { innerPadding ->
    Column(
        modifier = Modifier
            .padding(innerPadding)
            .consumeWindowInsets(innerPadding)
            .fitInside(WindowInsetsRulers.Ime.current)
            .verticalScroll(rememberScrollState())
    ) { /* Content */ }
}
<br />
以下示例正确,因为默认的
contentWindowInsets
不包含IME内边距,而
imePadding()
会应用IME内边距:
kotlin
// RIGHT
Scaffold() { innerPadding ->
    Column(
        modifier = Modifier
            .padding(innerPadding)
            .consumeWindowInsets(innerPadding)
            .imePadding()
            .verticalScroll(rememberScrollState())
    ) { /* Content */ }
}
<br />

WRONG

错误示例

WRONG because there will be excess padding when the IME opens. IME insets are applied twice, once with innerPadding, which contains IME insets from the passed
contentWindowInsets
values, and once with
imePadding
:
kotlin
// WRONG
Scaffold( contentWindowInsets = WindowInsets.safeDrawing ) { innerPadding ->
    Column(
        modifier = Modifier
            .padding(innerPadding)
            .imePadding()
            .verticalScroll(rememberScrollState())
    ) { /* Content */ }
}
<br />
WRONG because the IME will cover up the content. Scaffold's default
contentWindowInsets
does NOT contain IME insets.
kotlin
// WRONG
Scaffold() { innerPadding ->
    Column(
        modifier = Modifier
            .padding(innerPadding)
            .verticalScroll(rememberScrollState())
    ) { /* Content */ }
}
<br />
以下示例错误,因为当IME弹出时会出现多余内边距。IME内边距被应用了两次:一次是通过包含IME内边距的
innerPadding
(来自传入的
contentWindowInsets
值),另一次是通过
imePadding
kotlin
// WRONG
Scaffold( contentWindowInsets = WindowInsets.safeDrawing ) { innerPadding ->
    Column(
        modifier = Modifier
            .padding(innerPadding)
            .imePadding()
            .verticalScroll(rememberScrollState())
    ) { /* Content */ }
}
<br />
以下示例错误,因为IME会遮挡内容。Scaffold默认的
contentWindowInsets
不包含IME内边距。
kotlin
// WRONG
Scaffold() { innerPadding ->
    Column(
        modifier = Modifier
            .padding(innerPadding)
            .verticalScroll(rememberScrollState())
    ) { /* Content */ }
}
<br />

IMEs without Scaffolds code patterns

不使用Scaffold的IME代码规范

RIGHT

正确示例

The following code samples WILL NOT cause excessive padding.
kotlin
// RIGHT
Box(
    // Insets consumed
    modifier = Modifier.safeDrawingPadding() // or imePadding(), safeContentPadding(), safeGesturesPadding()
) {
    Column(
        modifier = Modifier.imePadding()
    ) { /* Content */ }
}
<br />
kotlin
// RIGHT
Box(
    // Insets consumed
    modifier = Modifier.windowInsetsPadding(WindowInsets.safeDrawing) // or WindowInsets.ime, WindowInsets.safeContent, WindowInsets.safeGestures
) {
    Column(
        modifier = Modifier.imePadding()
    ) { /* Content */ }
}
<br />
kotlin
// RIGHT
Box(
    // Insets not consumed, but irrelevant due to fitInside
    modifier = Modifier.padding(WindowInsets.safeDrawing.asPaddingValues()) // or WindowInsets.ime.asPaddingValues(), WindowInsets.safeContent.asPaddingValues(), WindowInsets.safeGestures.asPaddingValues()
) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .fitInside(WindowInsetsRulers.Ime.current)
    ) { /* Content */ }
}
<br />
以下代码示例不会导致多余内边距。
kotlin
// RIGHT
Box(
    // 内边距已被消费
    modifier = Modifier.safeDrawingPadding() // 或imePadding(), safeContentPadding(), safeGesturesPadding()
) {
    Column(
        modifier = Modifier.imePadding()
    ) { /* Content */ }
}
<br />
kotlin
// RIGHT
Box(
    // 内边距已被消费
    modifier = Modifier.windowInsetsPadding(WindowInsets.safeDrawing) // 或WindowInsets.ime, WindowInsets.safeContent, WindowInsets.safeGestures
) {
    Column(
        modifier = Modifier.imePadding()
    ) { /* Content */ }
}
<br />
kotlin
// RIGHT
Box(
    // 内边距未被消费,但fitInside不受此影响
    modifier = Modifier.padding(WindowInsets.safeDrawing.asPaddingValues()) // 或WindowInsets.ime.asPaddingValues(), WindowInsets.safeContent.asPaddingValues(), WindowInsets.safeGestures.asPaddingValues()
) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .fitInside(WindowInsetsRulers.Ime.current)
    ) { /* Content */ }
}
<br />

WRONG

错误示例

The following code sample WILL cause excessive padding because IME insets are applied twice:
kotlin
// WRONG
Box(
    // Insets not consumed
    modifier = Modifier.padding(WindowInsets.safeDrawing.asPaddingValues()) // or WindowInsets.ime.asPaddingValues(), WindowInsets.safeContent.asPaddingValues(), WindowInsets.safeGestures.asPaddingValues()
) {
    Column(
        modifier = Modifier.imePadding()
    ) { /* Content */ }
}
<br />
以下代码示例会导致多余内边距,因为IME内边距被应用了两次:
kotlin
// WRONG
Box(
    // 内边距未被消费
    modifier = Modifier.padding(WindowInsets.safeDrawing.asPaddingValues()) // 或WindowInsets.ime.asPaddingValues(), WindowInsets.safeContent.asPaddingValues(), WindowInsets.safeGestures.asPaddingValues()
) {
    Column(
        modifier = Modifier.imePadding()
    ) { /* Content */ }
}
<br />

Navigation Bar Contrast & System Bar Icons

导航栏对比度 & 系统栏图标

  • If the Activity uses
    enableEdgeToEdge
    from
    WindowCompat
    , you MUST set
    isAppearanceLightNavigationBars
    and
    isAppearanceLightStatusBars
    to the inverse of the device theme for apps that support light and dark theme so the system bar icons are legible. It's recommended to do this in your theme file. DO NOT do this if the Activities use
    enableEdgeToEdge
    from
    ComponentActivity
    because it handles the icon colors automatically.
    kotlin
    // Only use if calling `enableEdgeToEdge` from `WindowCompat`.
    // Apply to your theme file.
    @Composable
    fun MyTheme(
        darkTheme: Boolean = isSystemInDarkTheme(),
        content: @Composable () -> Unit
    ) {
        val view = LocalView.current
        if (!view.isInEditMode) {
            SideEffect {
                val window = (view.context as? Activity)?.window ?: return@SideEffect
                val controller = WindowCompat.getInsetsController(window, view)
    
                // Dark icons for Light Mode (!darkTheme), Light icons for Dark Mode
                controller.isAppearanceLightStatusBars = !darkTheme
                controller.isAppearanceLightNavigationBars = !darkTheme
            }
        }
    
        MaterialTheme(content = content)
    }
    <br />
  • If any screen uses a
    Scaffold
    or a
    NavigationSuiteScaffold
    with a bottom bar (e.g.,
    BottomAppBar
    ,
    NavigationBar
    ), set
    window.isNavigationBarContrastEnforced = false
    in the corresponding Activity for SDK 29+. This prevents the system from adding a translucent background to the navigation bar, verifying your bottom bar colors extend to the bottom of the screen.
  • 如果Activity使用
    WindowCompat
    中的
    enableEdgeToEdge
    ,你必须为支持亮色和暗色主题的应用设置
    isAppearanceLightNavigationBars
    isAppearanceLightStatusBars
    为设备主题的反值,以确保系统栏图标清晰可读。建议在主题文件中进行此设置。如果Activity使用
    ComponentActivity
    中的
    enableEdgeToEdge
    ,则无需进行此操作,因为它会自动处理图标颜色。
    kotlin
    // 仅当调用`WindowCompat`中的`enableEdgeToEdge`时使用。
    // 应用到你的主题文件中。
    @Composable
    fun MyTheme(
        darkTheme: Boolean = isSystemInDarkTheme(),
        content: @Composable () -> Unit
    ) {
        val view = LocalView.current
        if (!view.isInEditMode) {
            SideEffect {
                val window = (view.context as? Activity)?.window ?: return@SideEffect
                val controller = WindowCompat.getInsetsController(window, view)
    
                // 亮色主题使用深色图标(!darkTheme),暗色主题使用亮色图标
                controller.isAppearanceLightStatusBars = !darkTheme
                controller.isAppearanceLightNavigationBars = !darkTheme
            }
        }
    
        MaterialTheme(content = content)
    }
    <br />
  • 如果任何屏幕使用带有底部栏(如
    BottomAppBar
    NavigationBar
    )的
    Scaffold
    NavigationSuiteScaffold
    ,请在对应的Activity中为SDK 29+版本设置
    window.isNavigationBarContrastEnforced = false
    。这可以防止系统为导航栏添加半透明背景,确保你的底部栏颜色延伸至屏幕底部。

Lists

列表

  • Apply inset padding (like
    Scaffold
    's
    innerPadding
    ) to the
    contentPadding
    parameter of scrollable components (e.g.
    LazyColumn
    ,
    LazyRow
    ). DO NOT apply it as a
    Modifier.padding()
    to the list's parent container, as this clips the content and prevents it from scrolling behind the system bars.
  • Create a translucent composable covering the system bar so that the icons are still legible.
kotlin
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,
) {
    Spacer(
        modifier = Modifier
            .fillMaxWidth()
            .height(
                with(LocalDensity.current) {
                    (WindowInsets.statusBars.getTop(this) * 1.2f).toDp()
                }
            )
            .background(
                brush = Brush.verticalGradient(
                    colors = listOf(
                        color.copy(alpha = 1f),
                        color.copy(alpha = 0.8f),
                        Color.Transparent
                    )
                )
            )
    )
}
<br />
  • 为可滚动组件(如
    LazyColumn
    LazyRow
    )的
    contentPadding
    参数应用内边距(如
    Scaffold
    innerPadding
    )。请勿将其作为
    Modifier.padding()
    应用到列表的父容器,这会裁剪内容并阻止其在系统栏后方滚动。
  • 创建一个半透明的可组合组件覆盖系统栏,以确保图标仍然清晰可读。
kotlin
class SystemBarProtectionSnippets : ComponentActivity() {

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

        // enableEdgeToEdge会设置window.isNavigationBarContrastEnforced = true
        // 这会为三键导航添加半透明遮罩
        enableEdgeToEdge()

        setContent {
            MyTheme {
                // 主内容
                MyContent()

                // 绘制完主内容后,绘制状态栏遮罩
                StatusBarProtection()
            }
        }
    }
}

@Composable
private fun StatusBarProtection(
    color: Color = MaterialTheme.colorScheme.surfaceContainer,
) {
    Spacer(
        modifier = Modifier
            .fillMaxWidth()
            .height(
                with(LocalDensity.current) {
                    (WindowInsets.statusBars.getTop(this) * 1.2f).toDp()
                }
            )
            .background(
                brush = Brush.verticalGradient(
                    colors = listOf(
                        color.copy(alpha = 1f),
                        color.copy(alpha = 0.8f),
                        Color.Transparent
                    )
                )
            )
    )
}
<br />

Dialogs

对话框

If both the following conditions are true, then the Dialog is full screen and must be made edge-to-edge:
  1. The
    DialogProperties
    contains
    usePlatformDefaultWidth = false
    .
  2. The Dialog calls
    Modifier.fillMaxSize()
    .
To make a full screen Dialog edge-to-edge, set
decorFitsSystemWindows = false
in the
DialogProperties
.
kotlin
Dialog(
    onDismissRequest = { /* Handle dismiss */ },
    properties = DialogProperties(
        // 1. Allows the dialog to span the full width of the screen
        usePlatformDefaultWidth = false,
        // 2. Allows the dialog to draw behind status and navigation bars
        decorFitsSystemWindows = false
    )
) { /* Content */ }
<br />
如果同时满足以下两个条件,则该对话框为全屏对话框,必须设置为边缘到边缘显示:
  1. DialogProperties
    中包含
    usePlatformDefaultWidth = false
  2. 对话框调用了
    Modifier.fillMaxSize()
要将全屏对话框设置为边缘到边缘显示,请在
DialogProperties
中设置
decorFitsSystemWindows = false
kotlin
Dialog(
    onDismissRequest = { /* Handle dismiss */ },
    properties = DialogProperties(
        // 1. 允许对话框占满屏幕宽度
        usePlatformDefaultWidth = false,
        // 2. 允许对话框在状态栏和导航栏后方绘制
        decorFitsSystemWindows = false
    )
) { /* Content */ }
<br />

Checklist

检查清单

  • [ ] Does every
    Activity
    call
    enableEdgeToEdge()
    ?
  • [ ] Is
    adjustResize
    set in the
    AndroidManifest.xml
    ?
  • [ ] Does every
    TextField
    ,
    OutlinedTextField
    , or
    BasicTextField
    have a parent with
    imePadding()
    ,
    fitInside
    ,
    Modifier.safeDrawingPadding()
    ,
    Modifier.safeContentPadding()
    ,
    Modifier.safeGesturesPadding()
    , or
    contentWindowInsets
    set to
    WindowInsets.safeDrawing
    or
    WindowInsets.ime
    ?
  • [] Does the first and last list item draw away from the system bars by passing insets to
    contentPadding
    ?
  • [] Do FABs draw above the navigation bars by either being inside a Scaffold or by applying
    Modifier.safeDrawingPadding()
    ?
  • [] Does the project build? Run
    ./gradlew build
    to be sure.
  • 每个
    Activity
    都调用了
    enableEdgeToEdge()
    吗?
  • AndroidManifest.xml中是否设置了
    adjustResize
  • 每个
    TextField
    OutlinedTextField
    BasicTextField
    的父容器是否添加了
    imePadding()
    fitInside
    Modifier.safeDrawingPadding()
    Modifier.safeContentPadding()
    Modifier.safeGesturesPadding()
    ,或者将
    contentWindowInsets
    设置为
    WindowInsets.safeDrawing
    WindowInsets.ime
  • 列表的第一个和最后一个项是否通过传递内边距给
    contentPadding
    来避开系统栏?
  • FAB是否通过置于Scaffold内或应用
    Modifier.safeDrawingPadding()
    来显示在导航栏上方?
  • 项目能否正常构建?运行
    ./gradlew build
    以确认。