Создание приложений для телефонов, складных устройств и планшетов стало еще проще благодаря новым адаптивным макетам Material, которые уже находятся в альфа-версии.
Разнообразие размеров Android-устройств, представленных на рынке, не позволяет заранее определить размер экрана, с которым будет работать приложение. Разработчики не должны полагать, что экран прямоугольный или что экран, на котором приложение было запущено, является тем, на котором оно отображается в данный момент. Вместо этого разработчики должны адаптировать приложения к устройству, на котором они работают в данный момент, чтобы сделать их более удобными для пользователей.
Jetpack Compose упрощает динамическое проектирование пользовательского интерфейса и повторное использование компонентов, предоставляя современную альтернативу разработке пользовательского интерфейса на основе представлений и XML-файлов компоновки. Кроме того, классы размеров окон определяют конкретные размеры экрана, на основе которых можно принимать решения, например, показывать на экране одну панель или две. В GitHub-репозитории CanonicalLayouts можно увидеть примеры того, как это делается уже сегодня.
Адаптивные макеты Material
Для большого числа приложений правила работы с окнами разных размеров могут быть одинаковыми. Например, при определенном размере окна имеет смысл показать две панели рядом друг с другом или переключиться на боковое меню (навигационный рельс). Но большинство приложений вряд ли должны определять такое поведение индивидуально. Мы хотим упростить для вас принятие решений по компоновке, но в то же время предоставить гибкость в выборе пользовательского дизайна и поведения.
С этой целью мы выпустили первую альфа-версию наших новых адаптивных макетов Material. В первую очередь мы остановились на компонентах ListDetailPaneScaffold
и NavigationSuiteScaffold
.
Макет Список-Подробности
ListDetailPaneScaffold
— это composable , который берет компонент для списка и компонент для деталей и обрабатывает всю логику отображения одного элемента за раз или обоих рядом.
Чтобы использовать ListDetailPaneScaffold
, включите следующую новую зависимость в файл build.gradle модуля вашего приложения:
androidx.compose.material3:material3-adaptive
Сохраняйте состояние панели с помощью rememberListDetailPaneScaffoldState
, сохраняйте текущий выбранный элемент (если таковой имеется) и вызывайте ListDetailPaneScaffold
с помощью своих компонент:
// Copyright 2023 Google LLC. SPDX-License-Identifier: Apache-2.0 val state = rememberListDetailPaneScaffoldState() var selectedItem: MyItem? by rememberSaveable { mutableStateOf(null) } ListDetailPaneScaffold( scaffoldState = state, listPane = { MyList( onItemClick = { id -> // Set current item selectedItem = id // Display the details pane state.navigateTo(ListDetailPaneScaffoldRole.Detail) } ) }, detailPane = { // Show the details pane content if selected item is available selectedItem?.let { item -> MyDetails(item) } }, )
Код автоматически обрабатывает выбор отображения одной или обеих панелей при запуске приложения или при изменении конфигурации, например при повороте устройства или переходе в режим разделенного экрана.
Более подробно об использовании ListDetailPaneScaffold
см. в разделе Построение макета список-подробности.
Примечание: Мы еще не интегрировали поддержку библиотеки navigation-compose, но она находится в дорожной карте.
Навигационная панель или навигационный рельс
NavigationSuiteScaffold
автоматически использует наиболее подходящий для вашего приложения навигационный пользовательский интерфейс верхнего уровня для обеспечения максимальной доступности. В зависимости от текущего размера окна приложения пользовательский интерфейс переключается между нижней навигационной панелью и боковой навигационной шиной.
Чтобы использовать NavigationSuiteScaffold
, включите следующую новую зависимость в файл build.gradle вашего приложения:
androidx.compose.material3:material3-adaptive-navigation-suite
Затем создайте свой навигационный пользовательский интерфейс:
// Copyright 2023 Google LLC. SPDX-License-Identifier: Apache-2.0 var selectedItem by rememberSaveable { mutableIntStateOf(0) } val navItems = listOf("Songs", "Artists", "Playlists") val navSuiteType = NavigationSuiteScaffoldDefaults.calculateFromAdaptiveInfo(currentWindowAdaptiveInfo()) NavigationSuiteScaffold( navigationSuiteItems = { navItems.forEachIndexed { index, navItem -> item( icon = { Icon(Icons.Filled.Favorite, contentDescription = navItem) }, label = { Text(navItem) }, selected = selectedItem == index, onClick = { selectedItem = index } ) } } ) { // Screen content. Text( modifier = Modifier.padding(16.dp), text = "Current NavigationSuiteType: $navSuiteType" ) }
Если вы используете стандартный Scaffold
для отображения только нижней панели навигации и контента, то можете полностью заменить его на NavigationSuiteScaffold
. Если же скаффолд используется для отображения других элементов, таких как верхняя панель, плавающая кнопка действия или bottom sheet, то скаффолд можно переместить в лямбду содержимого NavigationSuiteScaffold
.
Что дальше?
Данный выпуск адаптивных макетов Material является альфа-версией, поэтому нам еще многое предстоит сделать. Мы активно улучшаем компоненты и добавляем новые. Мы также работаем над выделением из библиотеки material3-adaptive
более общих адаптивных компонент, не относящихся к Material.
Тем временем мы будем рады услышать ваше мнение. Добавляйте адаптивные макеты в свои приложения с помощью ListDetailPaneScaffold
и NavigationSuiteScaffold
и сообщайте нам о своем мнении, подавая запрос на исправление ошибки или предоставление возможности.