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