2

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
    }
}
slaviboy
  • 1,407
  • 17
  • 27
  • Have you tried running your app in release build with R8, like Chris Banes suggested in the linked issue? – Phil Dukhov Feb 01 '22 at 04:01
  • My bad, I gave the wrong link, this is the right issue I was talking about. For lagging when using padding https://github.com/google/accompanist/issues/349 – slaviboy Feb 01 '22 at 06:03

1 Answers1

0

I managed to fix it, by replacing the padding with offset, so the code for the Column is changed to:

Column(
    modifier = Modifier
        .fillMaxSize()
        .verticalScroll(state = scrollState, enabled = true)
        .offset { IntOffset(0, viewModel.swipeRefreshPaddingTop.value.roundToInt()) }
) {
}

And now there is no more lagging, even on older devices with 2GB RAM! I have no idea how this is related to the padding lagging, but it works. I found the code from HERE

slaviboy
  • 1,407
  • 17
  • 27