Кнопки со значками позволяют пользователям выполнять действия. Кнопки со значками должны содержать значок с понятным значением и обычно представлять распространенные или часто используемые действия.
Существует два типа кнопок со значками:
- По умолчанию. Эти кнопки могут открывать другие элементы, например меню или поиск.
- Переключатели. Эти кнопки могут представлять бинарные действия, которые можно включить или отключить, например "Добавить в избранное" или "Добавить в закладки".
Поверхность API
Используйте composable-функцию IconButton, чтобы реализовать стандартные кнопки со значками. Чтобы создать разные визуальные стили, например с заливкой, тональной заливкой или контуром, используйте FilledIconButton, FilledTonalIconButton и OutlinedIconButton соответственно.
Основные параметры для IconButton:
onClick– лямбда-функция, которая выполняется, когда пользователь нажимает кнопку со значком.enabled– логическое значение, определяющее, включена ли кнопка. Когдаfalse, кнопка не реагирует на ввод данных пользователем.content– контент, который можно составить внутри кнопки, обычноIcon.
Пример 1. Кнопка с переключателем
В этом примере показано, как реализовать кнопку с переключаемым значком. Значок переключателя меняет внешний вид в зависимости от того, выбран он или нет.
@Preview @Composable fun ToggleIconButtonExample() { // isToggled initial value should be read from a view model or persistent storage. var isToggled by rememberSaveable { mutableStateOf(false) } IconButton( onClick = { isToggled = !isToggled } ) { Icon( painter = if (isToggled) painterResource(R.drawable.favorite_filled) else painterResource(R.drawable.favorite), contentDescription = if (isToggled) "Selected icon button" else "Unselected icon button." ) } }
Ключевые моменты
- Composable-функция
ToggleIconButtonExampleопределяет переключательIconButton.mutableStateOf(false)создает объектMutableState, который содержит логическое значение, изначально равноеfalse. Это делаетisToggledдержателем состояния, а значит, Compose будет перекомпоновывать интерфейс всякий раз, когда его значение меняется.rememberSaveableгарантирует, что состояниеisToggledсохранится при изменении конфигурации, например при повороте экрана.
- Лямбда-функция
onClickэлементаIconButtonопределяет поведение кнопки при нажатии, переключая состояние междуtrueиfalse. - Параметр
painterфункцииIconусловно загружает другой элементpainterResourceв зависимости от состоянияisToggled. Это изменит внешний вид значка.- Если
isToggledимеет значениеtrue, загружается заполненный значок сердца. - Если
isToggled–false, загружается значок сердца с контуром.
- Если
contentDescriptionзначкаIconтакже меняется в зависимости отisToggled, чтобы предоставлять подходящую информацию о доступности.
Результат
На изображении ниже показана кнопка переключателя из предыдущего фрагмента кода в отключенном состоянии:
Расширенный пример: повторяющиеся действия при нажатии
В этом разделе рассказывается, как создать кнопки со значками, которые непрерывно выполняют действие, пока пользователь удерживает их нажатыми, а не только при клике.
@Composable fun MomentaryIconButton( unselectedImage: Int, selectedImage: Int, contentDescription: String, modifier: Modifier = Modifier, stepDelay: Long = 100L, // Minimum value is 1L milliseconds. onClick: () -> Unit ) { val interactionSource = remember { MutableInteractionSource() } val isPressed by interactionSource.collectIsPressedAsState() val pressedListener by rememberUpdatedState(onClick) LaunchedEffect(isPressed) { while (isPressed) { delay(stepDelay.coerceIn(1L, Long.MAX_VALUE)) pressedListener() } } IconButton( modifier = modifier, onClick = onClick, interactionSource = interactionSource ) { Icon( painter = if (isPressed) painterResource(id = selectedImage) else painterResource(id = unselectedImage), contentDescription = contentDescription, ) } }
Ключевые моменты
MomentaryIconButtonпринимаетunselectedImage: Int– идентификатор ресурса изображения для значка, когда кнопка не нажата, иselectedImage: Int– идентификатор ресурса изображения для значка, когда кнопка нажата.- В нем используется
interactionSource, чтобы отслеживать нажатия пользователя. isPressed– значение true, когда кнопка нажата, и false в противном случае. ЕслиisPressedравноtrue,LaunchedEffectпереходит в цикл.- Внутри цикла используется
delay(сstepDelay), чтобы создавать паузы между действиями.coerceInгарантирует, что задержка будет не менее 1 мс, чтобы предотвратить бесконечные циклы. - Функция
pressedListenerвызывается после каждой задержки в цикле. Это приведет к повторению действия.
- Внутри цикла используется
pressedListenerиспользуетrememberUpdatedState, чтобы гарантировать, чтоonClickлямбда (действие, которое нужно выполнить) всегда будет самой актуальной из последней композиции.- Изображение на кнопке
Iconменяется в зависимости от того, нажата она или нет.- Если параметр
isPressedимеет значение true, то строкаselectedImageбудет показана. - В противном случае будет показан значок
unselectedImage.
- Если параметр
Теперь используйте MomentaryIconButton в примере. В следующем фрагменте кода показаны две кнопки со значками, управляющие счетчиком:
@Preview() @Composable fun MomentaryIconButtonExample() { var pressedCount by remember { mutableIntStateOf(0) } Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { MomentaryIconButton( unselectedImage = R.drawable.fast_rewind, selectedImage = R.drawable.fast_rewind_filled, stepDelay = 100L, onClick = { pressedCount -= 1 }, contentDescription = "Decrease count button" ) Spacer(modifier = Modifier) Text("advanced by $pressedCount frames") Spacer(modifier = Modifier) MomentaryIconButton( unselectedImage = R.drawable.fast_forward, selectedImage = R.drawable.fast_forward_filled, contentDescription = "Increase count button", stepDelay = 100L, onClick = { pressedCount += 1 } ) } }
Ключевые моменты
- Компонуемый элемент
MomentaryIconButtonExampleсодержит компонуемый элементRowс двумя экземплярамиMomentaryIconButtonи компонуемый элементText, который используется для создания интерфейса счетчика. - Она поддерживает изменяемую переменную состояния
pressedCount, используяrememberиmutableIntStateOf, инициализированные значением 0. Когда значениеpressedCountменяется, все наблюдающие за ним composable-функции (например,Text) перекомпонуются, чтобы отразить новое значение. - Первая кнопка
MomentaryIconButtonуменьшает громкостьpressedCountпри нажатии или удерживании. - Второй элемент
MomentaryIconButtonувеличивает значениеpressedCountпри нажатии или удержании. - Обе кнопки используют
stepDelayв 100 миллисекунд, то есть действиеonClickповторяется каждые 100 мс, пока кнопка удерживается.
Результат
На видео ниже показан интерфейс с кнопками и счетчиком: