Навигационный ящик

Компонент выдвижной навигации представляет собой выдвижное меню, позволяющее пользователям переходить к различным разделам вашего приложения. Пользователи могут активировать его, проведя пальцем сбоку или нажав на значок меню.

Рассмотрим три варианта использования выдвижной навигационной панели:

  • Организация контента: Предоставьте пользователям возможность переключаться между различными категориями, например, в новостных или блог-приложениях.
  • Управление учетными записями: Предоставьте быстрые ссылки на настройки учетной записи и разделы профиля в приложениях с пользовательскими учетными записями.
  • Обнаружение функций: Организуйте множество функций и настроек в одном меню, чтобы упростить поиск и доступ к ним для пользователей в сложных приложениях.

В Material Design существует два типа боковых навигационных панелей:

  • Стандартный режим: делить пространство экрана с другим контентом.
  • Модальное окно: появляется поверх остального контента на экране.
Пример бокового меню навигации в стиле Material Design 3 в светлом и темном режимах.
Рисунок 1. Пример выдвижной навигационной панели.

Пример

Для реализации выдвижной навигационной панели можно использовать составной объект ModalNavigationDrawer .

Используйте слот drawerContent для предоставления объекта ModalDrawerSheet и указания содержимого выдвижной панели, как показано в следующем примере:

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            Text("Drawer title", modifier = Modifier.padding(16.dp))
            HorizontalDivider()
            NavigationDrawerItem(
                label = { Text(text = "Drawer Item") },
                selected = false,
                onClick = { /*TODO*/ }
            )
            // ...other drawer items
        }
    }
) {
    // Screen content
}

ModalNavigationDrawer принимает ряд дополнительных параметров для бокового меню. Например, вы можете переключать реагирование бокового меню на перетаскивание с помощью параметра gesturesEnabled , как показано в следующем примере:

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            // Drawer contents
        }
    },
    gesturesEnabled = false
) {
    // Screen content
}

Контроль поведения

Для управления открытием и закрытием выдвижной панели используйте DrawerState . Вам следует передать DrawerState в ModalNavigationDrawer , используя параметр drawerState .

DrawerState предоставляет доступ к функциям open и close , а также к свойствам, связанным с текущим состоянием выдвижной панели. Для этих приостанавливаемых функций требуется CoroutineScope , который можно создать с помощью rememberCoroutineScope . Вы также можете вызывать приостанавливаемые функции в ответ на события пользовательского интерфейса.

val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()
ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        ModalDrawerSheet { /* Drawer content */ }
    },
) {
    Scaffold(
        floatingActionButton = {
            ExtendedFloatingActionButton(
                text = { Text("Show drawer") },
                icon = { Icon(Icons.Filled.Add, contentDescription = "") },
                onClick = {
                    scope.launch {
                        drawerState.apply {
                            if (isClosed) open() else close()
                        }
                    }
                }
            )
        }
    ) { contentPadding ->
        // Screen content
    }
}

Создавайте группы внутри выдвижной навигационной панели.

Следующий фрагмент кода демонстрирует, как создать подробную выдвижную навигационную панель с разделами и перегородками:

@Composable
fun DetailedDrawerExample(
    content: @Composable (PaddingValues) -> Unit
) {
    val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
    val scope = rememberCoroutineScope()

    ModalNavigationDrawer(
        drawerContent = {
            ModalDrawerSheet {
                Column(
                    modifier = Modifier.padding(horizontal = 16.dp)
                        .verticalScroll(rememberScrollState())
                ) {
                    Spacer(Modifier.height(12.dp))
                    Text("Drawer Title", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleLarge)
                    HorizontalDivider()

                    Text("Section 1", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleMedium)
                    NavigationDrawerItem(
                        label = { Text("Item 1") },
                        selected = false,
                        onClick = { /* Handle click */ }
                    )
                    NavigationDrawerItem(
                        label = { Text("Item 2") },
                        selected = false,
                        onClick = { /* Handle click */ }
                    )

                    HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))

                    Text("Section 2", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleMedium)
                    NavigationDrawerItem(
                        label = { Text("Settings") },
                        selected = false,
                        icon = { Icon(Icons.Outlined.Settings, contentDescription = null) },
                        badge = { Text("20") }, // Placeholder
                        onClick = { /* Handle click */ }
                    )
                    NavigationDrawerItem(
                        label = { Text("Help and feedback") },
                        selected = false,
                        icon = { Icon(Icons.AutoMirrored.Outlined.Help, contentDescription = null) },
                        onClick = { /* Handle click */ },
                    )
                    Spacer(Modifier.height(12.dp))
                }
            }
        },
        drawerState = drawerState
    ) {
        Scaffold(
            topBar = {
                TopAppBar(
                    title = { Text("Navigation Drawer Example") },
                    navigationIcon = {
                        IconButton(onClick = {
                            scope.launch {
                                if (drawerState.isClosed) {
                                    drawerState.open()
                                } else {
                                    drawerState.close()
                                }
                            }
                        }) {
                            Icon(Icons.Default.Menu, contentDescription = "Menu")
                        }
                    }
                )
            }
        ) { innerPadding ->
            content(innerPadding)
        }
    }
}

Основные моменты, касающиеся кода.

  • Заполняет элемент drawerContent Column , содержащим разделители, панели и элементы навигации.
  • ModalDrawerSheet предоставляет стили Material Design для выдвижной панели.
  • HorizontalDivider разделяет секции внутри выдвижного ящика.
  • ModalNavigationDrawer создает выдвижную панель.
  • drawerContent определяет содержимое выдвижной панели.
  • Внутри ModalDrawerSheet Column располагает элементы выдвижной панели вертикально.
  • Компоненты NavigationDrawerItem представляют собой отдельные элементы в выдвижной панели.
  • Scaffold обеспечивает базовую структуру экрана, включая панель TopAppBar .
  • navigationIcon в TopAppBar управляет состоянием открытия и закрытия выдвижной панели.

Результат

На следующем изображении показано, как выглядит выдвижной ящик в открытом состоянии, с отображаемыми секциями и элементами:

Подробная выдвижная навигационная панель с двумя разделами, каждый из которых содержит несколько элементов с подписями и значками.
Рисунок 2. Открытая панель навигации с двумя вложенными группами.

Дополнительные ресурсы