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