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