Компонент «Потяните для обновления» позволяет пользователям перетаскивать вниз начало содержимого приложения, чтобы обновить данные.
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
. Таким образом, вы можете повторно использовать поведение и стили по умолчанию из библиотеки Material, настраивая только те элементы, которые вам нужны. -
MyCustomIndicator
используетCrossfade
для перехода между значком облака и индикаторомCircularProgressIndicator
. Значок облака увеличивается по мере перемещения пользователя и превращается в индикаторCircularProgressIndicator
при начале обновления.-
targetState
используетisRefreshing
для определения, какое состояние отображать (значок облака или круговой индикатор прогресса). -
animationSpec
определяет анимациюtween
с указанной длительностьюCROSSFADE_DURATION_MILLIS
. -
state.distanceFraction
показывает, насколько далеко пользователь потянул ползунок вниз, в диапазоне от0f
(нет нажатия) до1f
(полностью потянуто). - Модификатор
graphicsLayer
изменяет масштаб и прозрачность.
-
Результат
В этом видео показан пользовательский индикатор из предыдущего кода: