Компонент обновления позволяет пользователям перетаскивать вниз начало содержимого приложения, чтобы обновить данные.
поверхность API
Используйте составной элемент PullToRefreshBox
для реализации обновления по запросу, который действует как контейнер для прокручиваемого содержимого. Следующие ключевые параметры управляют поведением и внешним видом обновления:
-
isRefreshing
: логическое значение, указывающее, выполняется ли в данный момент действие обновления. -
onRefresh
: лямбда-функция, которая выполняется, когда пользователь инициирует обновление. -
indicator
: настраивает индикатор, который отображается при обновлении.
Базовый пример
Этот фрагмент демонстрирует базовое использование PullToRefreshBox
:
@Composable fun PullToRefreshBasicSample( items: List<String>, isRefreshing: Boolean, onRefresh: () -> Unit, modifier: Modifier = Modifier ) { PullToRefreshBox( isRefreshing = isRefreshing, onRefresh = onRefresh, modifier = modifier ) { LazyColumn(Modifier.fillMaxSize()) { items(items) { ListItem({ Text(text = it) }) } } } }
Ключевые моменты о коде
-
PullToRefreshBox
оборачиваетLazyColumn
, который отображает список строк. -
PullToRefreshBox
требует параметровisRefreshing
иonRefresh
. - Содержимое блока
PullToRefreshBox
представляет собой прокручиваемый контент.
Результат
В этом видео демонстрируется базовая реализация обновления по запросу из предыдущего кода:
Расширенный пример: настройка цвета индикатора
@Composable fun PullToRefreshCustomStyleSample( items: List<String>, isRefreshing: Boolean, onRefresh: () -> Unit, modifier: Modifier = Modifier ) { val state = rememberPullToRefreshState() PullToRefreshBox( isRefreshing = isRefreshing, onRefresh = onRefresh, modifier = modifier, state = state, indicator = { Indicator( modifier = Modifier.align(Alignment.TopCenter), isRefreshing = isRefreshing, containerColor = MaterialTheme.colorScheme.primaryContainer, color = MaterialTheme.colorScheme.onPrimaryContainer, state = state ) }, ) { LazyColumn(Modifier.fillMaxSize()) { items(items) { ListItem({ Text(text = it) }) } } } }
Ключевые моменты о коде
- Цвет индикатора настраивается с помощью свойств
containerColor
иcolor
в параметреindicator
. -
rememberPullToRefreshState()
управляет состоянием действия обновления. Вы используете это состояние вместе с параметромindicator
.
Результат
В этом видео показана реализация обновления по запросу с цветным индикатором:
Расширенный пример: создание полностью настраиваемого индикатора
Вы можете создавать сложные пользовательские индикаторы, используя существующие составные элементы и анимацию. В этом фрагменте показано, как создать полностью настраиваемый индикатор в вашей реализации с возможностью обновления по запросу:
@Composable fun PullToRefreshCustomIndicatorSample( items: List<String>, isRefreshing: Boolean, onRefresh: () -> Unit, modifier: Modifier = Modifier ) { val state = rememberPullToRefreshState() PullToRefreshBox( isRefreshing = isRefreshing, onRefresh = onRefresh, modifier = modifier, state = state, indicator = { MyCustomIndicator( state = state, isRefreshing = isRefreshing, modifier = Modifier.align(Alignment.TopCenter) ) } ) { LazyColumn(Modifier.fillMaxSize()) { items(items) { ListItem({ Text(text = it) }) } } } } // ... @Composable fun MyCustomIndicator( state: PullToRefreshState, isRefreshing: Boolean, modifier: Modifier = Modifier, ) { Box( modifier = modifier.pullToRefreshIndicator( state = state, isRefreshing = isRefreshing, containerColor = PullToRefreshDefaults.containerColor, threshold = PositionalThreshold ), contentAlignment = Alignment.Center ) { Crossfade( targetState = isRefreshing, animationSpec = tween(durationMillis = CROSSFADE_DURATION_MILLIS), modifier = Modifier.align(Alignment.Center) ) { refreshing -> if (refreshing) { CircularProgressIndicator(Modifier.size(SPINNER_SIZE)) } else { val distanceFraction = { state.distanceFraction.coerceIn(0f, 1f) } Icon( imageVector = Icons.Filled.CloudDownload, contentDescription = "Refresh", modifier = Modifier .size(18.dp) .graphicsLayer { val progress = distanceFraction() this.alpha = progress this.scaleX = progress this.scaleY = progress } ) } } } }
Ключевые моменты о коде
- В предыдущем фрагменте использовался
Indicator
предоставленный библиотекой. Этот фрагмент кода создает составной пользовательский индикатор под названиемMyCustomIndicator
. В этом компонуемом модификаторpullToRefreshIndicator
управляет позиционированием и запуском обновления. - Как и в предыдущем фрагменте, экземпляр
PullToRefreshState
был извлечен, поэтому один и тот же экземпляр можно передать как вPullToRefreshBox
, так и вpullToRefreshModifier
. - Цвет контейнера и порог позиции используются из класса
PullToRefreshDefaults
. Таким образом, вы можете повторно использовать поведение и стиль по умолчанию из библиотеки материалов, настраивая при этом только те элементы, которые вас интересуют. -
MyCustomIndicator
используетCrossfade
для перехода между значком облака иCircularProgressIndicator
. Значок облака увеличивается по мере того, как пользователь тянет его, и превращается вCircularProgressIndicator
, когда начинается действие обновления.-
targetState
используетisRefreshing
, чтобы определить, какое состояние отображать (значок облака или круговой индикатор прогресса). -
animationSpec
определяет анимациюtween
с указанной длительностьюCROSSFADE_DURATION_MILLIS
. -
state.distanceFraction
показывает, насколько далеко пользователь продвинулся вниз, в диапазоне от0f
(нет вытягивания) до1f
(полное вытягивание). - Модификатор
graphicsLayer
изменяет масштаб и прозрачность.
-
Результат
В этом видео показан пользовательский индикатор из предыдущего кода: