Компонент "Потянуть, чтобы обновить" позволяет пользователям перетаскивать вниз начало контента приложения, чтобы обновить данные.
API surface
Используйте composable-функцию 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-функции и анимации.В этом фрагменте кода показано, как создать полностью настраиваемый индикатор в реализации функции "Потянуть, чтобы обновить":
@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( painter = rememberVectorPainter(AppIcons.CloudDownload), contentDescription = "Refresh", modifier = Modifier .size(18.dp) .graphicsLayer { val progress = distanceFraction() this.alpha = progress this.scaleX = progress this.scaleY = progress } ) } } } }
Важные сведения о коде
- В предыдущем фрагменте использовался метод
Indicator, предоставляемый библиотекой. Этот фрагмент создает настраиваемый индикатор composable с именемMyCustomIndicator. В этой composable-функции модификаторpullToRefreshIndicatorотвечает за позиционирование и запуск обновления. - Как и в предыдущем фрагменте, в примере извлекается экземпляр
PullToRefreshState, поэтому вы можете передать один и тот же экземпляр как вPullToRefreshBox, так и вpullToRefreshModifier. - В примере используются цвет контейнера и пороговое значение позиции из класса
PullToRefreshDefaults. Таким образом, вы можете повторно использовать поведение и стиль по умолчанию из библиотеки Material, настраивая только те элементы, которые вас интересуют. MyCustomIndicatorиспользуетCrossfadeдля перехода между значком облака иCircularProgressIndicator. По мере того как пользователь тянет экран вниз, значок облака увеличивается, а когда начинается обновление, превращается вCircularProgressIndicator.targetStateиспользуетisRefreshing, чтобы определить, какое состояние отображать (значок облака или кольцевой индикатор прогресса).animationSpecопределяет анимациюtweenдля перехода с указанной длительностьюCROSSFADE_DURATION_MILLIS.state.distanceFraction– это расстояние, на которое пользователь потянул экран вниз. Значение может быть от0f(не потянул) до1f(потянул полностью).- Модификатор
graphicsLayerизменяет масштаб и прозрачность.
Результат
В этом видео показан пользовательский индикатор из предыдущего кода: