Android Jetpack Compose (Composable) 如何正确实现滑动刷新
Android Jetpack Compose (Composable) How to properly implement Swipe Refresh
我使用伴奏库中的 SwipeRefresh 可组合项,我检查了 examples, but I could not find sample that matches my needs. I want to implement element that is hidden above the main UI, so when the user starts swiping the box is slowly shown up. I implemented this logic by setting the padding of the box that is below the hidden box. The obvious reason is that by changing the padding, all the composables are recreated and that leads to lags as seen from this report。有办法解决吗?
@Composable
fun HomeScreen(viewModel: CityWeatherViewModel) {
val scrollState = rememberScrollState()
val maxTopOffset = 200f
SwipeRefresh(
state = rememberSwipeRefreshState(isRefreshing = isRefreshing),
onRefresh = {
},
indicator = { state, triggerDp ->
if (state.isRefreshing) {
} else {
val triggerPx = with(LocalDensity.current) { triggerDp.toPx() }
val progress = (state.indicatorOffset / triggerPx).coerceIn(0f, 1f)
viewModel.apply {
rotateSwipeRefreshArrow(progress >= 0.9)
setSwipeRefreshTopPadding(progress * maxTopOffset)
}
}
}
) {
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(state = scrollState, enabled = true)
.padding(top = viewModel.swipeRefreshPaddingTop.value.dp)
) {
HiddenSwipeRefreshBox(viewModel)
MainBox(viewModel)
}
}
}
@Composable
fun HiddenSwipeRefreshBox(viewModel: CityWeatherViewModel) {
}
@Composable
fun MainBox(viewModel: CityWeatherViewModel) {
}
@HiltViewModel
class CityWeatherViewModel @Inject constructor(
private val getCityWeather: GetCityWeather
) : ViewModel() {
private val _swipeRefreshPaddingTop = mutableStateOf(0f)
val swipeRefreshPaddingTop: State<Float> = _swipeRefreshPaddingTop
fun setSwipeRefreshTopPadding(padding: Float) {
_swipeRefreshPaddingTop.value = padding
}
}
我设法修复了它,将 padding 替换为 offset,所以Column的代码改为:
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(state = scrollState, enabled = true)
.offset { IntOffset(0, viewModel.swipeRefreshPaddingTop.value.roundToInt()) }
) {
}
现在不再有滞后现象,即使在具有 2GB RAM 的旧设备上也是如此!我不知道这与填充滞后有何关系,但它有效。我从 HERE
中找到了代码
我使用伴奏库中的 SwipeRefresh 可组合项,我检查了 examples, but I could not find sample that matches my needs. I want to implement element that is hidden above the main UI, so when the user starts swiping the box is slowly shown up. I implemented this logic by setting the padding of the box that is below the hidden box. The obvious reason is that by changing the padding, all the composables are recreated and that leads to lags as seen from this report。有办法解决吗?
@Composable
fun HomeScreen(viewModel: CityWeatherViewModel) {
val scrollState = rememberScrollState()
val maxTopOffset = 200f
SwipeRefresh(
state = rememberSwipeRefreshState(isRefreshing = isRefreshing),
onRefresh = {
},
indicator = { state, triggerDp ->
if (state.isRefreshing) {
} else {
val triggerPx = with(LocalDensity.current) { triggerDp.toPx() }
val progress = (state.indicatorOffset / triggerPx).coerceIn(0f, 1f)
viewModel.apply {
rotateSwipeRefreshArrow(progress >= 0.9)
setSwipeRefreshTopPadding(progress * maxTopOffset)
}
}
}
) {
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(state = scrollState, enabled = true)
.padding(top = viewModel.swipeRefreshPaddingTop.value.dp)
) {
HiddenSwipeRefreshBox(viewModel)
MainBox(viewModel)
}
}
}
@Composable
fun HiddenSwipeRefreshBox(viewModel: CityWeatherViewModel) {
}
@Composable
fun MainBox(viewModel: CityWeatherViewModel) {
}
@HiltViewModel
class CityWeatherViewModel @Inject constructor(
private val getCityWeather: GetCityWeather
) : ViewModel() {
private val _swipeRefreshPaddingTop = mutableStateOf(0f)
val swipeRefreshPaddingTop: State<Float> = _swipeRefreshPaddingTop
fun setSwipeRefreshTopPadding(padding: Float) {
_swipeRefreshPaddingTop.value = padding
}
}
我设法修复了它,将 padding 替换为 offset,所以Column的代码改为:
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(state = scrollState, enabled = true)
.offset { IntOffset(0, viewModel.swipeRefreshPaddingTop.value.roundToInt()) }
) {
}
现在不再有滞后现象,即使在具有 2GB RAM 的旧设备上也是如此!我不知道这与填充滞后有何关系,但它有效。我从 HERE
中找到了代码