'Android Jetpack Compose (Composable) How to properly implement Swipe Refresh

I use the SwipeRefresh composable from the accompanist library, I checked the 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. Is there a way to fix it?

enter image description here

@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
    }
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source