По умолчанию Jetpack Compose предоставляет два компонента для создания верхней и нижней панели в приложении.
Компонент TopAppBar позволяет определить верхнюю панель приложения. Он имеет следующие параметры:
@ExperimentalMaterial3Api @Composable fun TopAppBar( title: @Composable () -> Unit, modifier: Modifier = Modifier, navigationIcon: @Composable () -> Unit = {}, actions: @Composable RowScope.() -> Unit = {}, windowInsets: WindowInsets = TopAppBarDefaults.windowInsets, colors: TopAppBarColors = TopAppBarDefaults.topAppBarColors(), scrollBehavior: TopAppBarScrollBehavior? = null ): Unit
Параметры функции компонента:
title
: задает заголовок панели.
modifier
: представляет объект Modifier, который определяет модификаторы панели
navigationIcon
: задает иконку навигации (обычно компонент IconButton), которая отображается в начале панели
actions
: набор значков, отображаемых в конце панели. Обычно это кнопки IconButton
. ДЛя расположения иконок по умолчанию применяется контейнер
Row
, поэтому иконки располагаются по горизонтали.
windowInsets
: отступы от сторон окна
colors
: цвета панели в виде объекта TopAppBarColors. Для установки применяется функция TopAppBarDefaults.topAppBarColors()
.
scrollBehavior
: задает поведение при прокрутке с помощью объекта TopAppBarScrollBehavior.
На момент написания текущей статьи данный компонент помечен как экспериментальный. Поэтому при его использовании к родительскому компоненту следует применять аннотацию
@OptIn(ExperimentalMaterial3Api::class)
. Определим простейшую панель TopAppBar:
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.Menu import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.ui.unit.sp class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent @OptIn(ExperimentalMaterial3Api::class){ TopAppBar(title= { Text("METANIT.COM", fontSize = 22.sp)}, navigationIcon={ IconButton({ }) { Icon(Icons.Filled.Menu, contentDescription = "Меню")}}, actions={ IconButton({ }) { Icon(Icons.Filled.Info, contentDescription = "О приложении")} IconButton({ }) {Icon(Icons.Filled.Search, contentDescription = "Поиск")} }) } } }
В данном случае в самом начале панели располагается иконка навигации navigationIcon
(здесь в этом качестве выступает иконка Icons.Filled.Menu
).
Затем идет заголовок, который определяется функцией из title
. И в правой части панели располагаются дополнительные иконки (здесь Icons.Filled.Info
и
Icons.Filled.Search
), которые представляют дополнительные действия в приложении. В данном случае для каждого компонента IconButton параметр onClick
представляет пустое лямбда-выражение, поэтому при нажатии естественно никаких реальных действий не происходит.
Для установки цвета верхней панели применяется объект TopAppBarColors
. Для создания этого объекта удобно использовать функцию-компонент TopAppBarDefaults.topAppBarColors
:
@Composable fun topAppBarColors( containerColor: Color = Color.Unspecified, scrolledContainerColor: Color = Color.Unspecified, navigationIconContentColor: Color = Color.Unspecified, titleContentColor: Color = Color.Unspecified, actionIconContentColor: Color = Color.Unspecified ): TopAppBarColors
Эта функция предполагает установку следующих цветов:
containerColor
: цвет контейнера
scrolledContainerColor
: цвет контейнера при прокрутке содержимого за ним
navigationIconContentColor
: цвет содержимого, используемый для значка навигации
titleContentColor
: цвет содержимого, используемый для заголовка
actionIconContentColor
: цвет контента, используемый для действий
По умолчанию все эти цвета не указаны, соответственно панель не имеет цвета. Теперь настроим цвета:
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.Menu import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.sp class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent @OptIn(ExperimentalMaterial3Api::class){ TopAppBar(title= { Text("METANIT.COM", fontSize = 22.sp)}, navigationIcon={ IconButton({ }) { Icon(Icons.Filled.Menu, contentDescription = "Меню")}}, actions={ IconButton({ }) { Icon(Icons.Filled.Info, contentDescription = "О приложении")} IconButton({ }) {Icon(Icons.Filled.Search, contentDescription = "Поиск")} }, colors=TopAppBarDefaults.topAppBarColors(containerColor = Color.DarkGray, titleContentColor = Color.LightGray, navigationIconContentColor = Color.LightGray, actionIconContentColor = Color.LightGray)) } } }
Компонент BottomAppBar позволяет определить нижнюю панель. Он имеет ряд похожих версий. Возьмем одну из них:
@Composable fun BottomAppBar( modifier: Modifier = Modifier, containerColor: Color = BottomAppBarDefaults.containerColor, contentColor: Color = contentColorFor(containerColor), tonalElevation: Dp = BottomAppBarDefaults.ContainerElevation, contentPadding: PaddingValues = BottomAppBarDefaults.ContentPadding, windowInsets: WindowInsets = BottomAppBarDefaults.windowInsets, content: @Composable RowScope.() -> Unit ): Unit
Параметры функции компонента:
modifier
: представляет объект Modifier, который определяет модификаторы панели
containerColor
: значение типа Color
, которое задает фоновый цвет панели
contentColor
: значение типа Color
, которое устанавливает предпочтительный цвет для содержимого панели.
По умолчанию предоставляет вызов contentColorFor(containerColor)
, которое для установки использует значение параметра bcontainerColor
windowInsets
: устанавливает отступы от границ
tonalElevation
: определяет эффект анимацию для содержимого панели
contentPadding
: объект типа PaddingValues, который устанавливает отступы между границами панели и ее содержимым.
windowInsets
: устанавливает отступы от границ окна
content
: задает контент панели. По умолчанию содержимое располагается в виде строки с помощью контейнера
Row
. Обычно здесь располагаются компоненты IconButton, по нажатию на которые выполняются определенные действия.
Определим простейший BottomAppBar:
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.Menu import androidx.compose.material3.BottomAppBar import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text import androidx.compose.ui.Modifier import androidx.compose.ui.unit.sp class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Column(Modifier.fillMaxSize(), verticalArrangement = Arrangement.SpaceBetween){ Text("Main Content", fontSize = 28.sp) BottomAppBar{ IconButton(onClick = { }) { Icon(Icons.Filled.Menu, contentDescription = "Меню") } IconButton(onClick = { }) { Icon(Icons.Filled.Info, contentDescription = "О приложении") } IconButton(onClick = { }) { Icon(Icons.Filled.Search, contentDescription = "Поиск") } } } } } }
В качестве формального содержимого здесь определен компонент Text с некоторым текстом, а внизу столбца располагается нижняя панель приложения с тремя иконками.
По умолчанию все вложенные компоненты панели располагаются рядом друг с другом. Но иногда требуется сделать между ними некоторый зазор. Так, в примере выше мы, возможно, захотим разместить две последние иконки в правой части панели (как в случае с TopAppBar). Чтобы установить пустое пространство между компонентами Compose предоставляет специальный компонент Spacer. Этот компонент просто определяет пустую область, которая соответствует его размеру. Например:
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.Menu import androidx.compose.material3.BottomAppBar import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text import androidx.compose.ui.Modifier import androidx.compose.ui.unit.sp class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Column(Modifier.fillMaxSize(), verticalArrangement = Arrangement.SpaceBetween){ Text("Main Content", fontSize = 28.sp) BottomAppBar{ IconButton(onClick = { }) { Icon(Icons.Filled.Menu, contentDescription = "Меню") } Spacer(Modifier.weight(1f, true)) IconButton(onClick = { }) { Icon(Icons.Filled.Info, contentDescription = "О приложении") } IconButton(onClick = { }) { Icon(Icons.Filled.Search, contentDescription = "Поиск") } } } } } }
Здесь в Spacer растягивается на все незанятое другими компонентами пространство с помощью установки модификатора Modifier.weight(1f, true)
.
С помощью параметров containerColor
и contentColor
можно настроить цвет саой панели BottomAppBar и ее компонентов соответственно:
package com.example.helloapp import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Search import androidx.compose.material.icons.filled.Menu import androidx.compose.material3.BottomAppBar import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.sp class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Column(Modifier.fillMaxSize(), verticalArrangement = Arrangement.SpaceBetween){ Text("Main Content", fontSize = 28.sp) BottomAppBar( containerColor = Color.DarkGray, contentColor = Color.LightGray ){ IconButton(onClick = { }) { Icon(Icons.Filled.Menu, contentDescription = "Меню") } Spacer(Modifier.weight(1f, true)) IconButton(onClick = { }) { Icon(Icons.Filled.Info, contentDescription = "О приложении") } IconButton(onClick = { }) { Icon(Icons.Filled.Search, contentDescription = "Поиск") } } } } } }
Стоит отметить, что Jetpack Compose также предоставляет компоненты, которые позволяют автоматически разместить верхнюю и нижнюю панель соответственно вверху и внизу окна приложения и которые мы далее рассмотрим.