Компонент «Потяните для обновления» позволяет пользователям перетаскивать вниз начало содержимого приложения, чтобы обновить данные.
API поверхность
Используйте PullToRefreshBox
composable для реализации pull-to-refresh, который действует как контейнер для вашего прокручиваемого контента. Следующие ключевые параметры управляют поведением и внешним видом обновления:
-
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
изменяет масштаб и прозрачность.
-
Результат
В этом видео показан пользовательский индикатор из предыдущего кода: