Home > Back-end >  How to have a LazyColumn with a Composable like a Text("You are at the Top of the List"),
How to have a LazyColumn with a Composable like a Text("You are at the Top of the List"),

Time:09-17

I have a Column and a LazyColumn with the following code:

    Column {

        LazyColumn(
            modifier = Modifier.weight(1f),
            contentPadding = PaddingValues(top = 8.dp)
        ) {

            items(items = items) { it ->
                TodoRow(
                    todo = it,
                    onItemClicked = { onRemoveItem(it) },
                    modifier = Modifier.fillParentMaxWidth()
                )
            }
        }

    }

What I would like to obtain is the following:

  • To have a Box() with a Text() that explains that we are at the "Top of the List";
  • This Box() with Text() can`t be fixed. That is, it fades away as the list turns bigger and occupies all the screen. If we scroll up the Text() appears again.

For the Box with a Text I have the following code:

Box(
    modifier = Modifier
          .fillMaxWidth()
          .padding(start = 8.dp, end = 8.dp)
          .background(color = Color.LightGray),
    contentAlignment = Alignment.Center
 )
 { Text("Top of the List", modifier = Modifier.padding(vertical = 8.dp)) }

If I put this Box as a child of the above Column before the LazyColumn, this Box will be fixed, and I don`t want that.

So, where shall I put this Box? Can you help me?

Thanks

CodePudding user response:

You can read scroll position from the list state. Depending on the position you can calculate progress for your "animation".

Column {
    val listState = rememberLazyListState()
    val topOfListProgress: Float by remember {
        derivedStateOf {
            listState.run {
                if (firstVisibleItemIndex > 0) {
                    0f
                } else {
                    layoutInfo.visibleItemsInfo
                        .firstOrNull()
                        ?.let {
                            1f - firstVisibleItemScrollOffset.toFloat() / it.size
                        } ?: 1f
                }
            }
        }
    }
    Box(
        contentAlignment = Alignment.Center,
        modifier = Modifier
            .fillMaxWidth()
            .padding(start = 8.dp, end = 8.dp)
            .background(color = Color.LightGray)
            .layout { measurable, constraints ->
                val placeable = measurable.measure(constraints)
                val offset = (placeable.height * (1f - topOfListProgress)).roundToInt()
                layout(placeable.width, placeable.height - offset) {
                    placeable.place(0, -offset)
                }
            }
            .alpha(topOfListProgress)
    ) {
        Text("Top of the List", modifier = Modifier.padding(vertical = 8.dp))
    }

    LazyColumn(
        state = listState,
        contentPadding = PaddingValues(top = 8.dp),
        modifier = Modifier
                .weight(1f)
    ) {
        items(100) {
            Text(it.toString())
        }
    }
}

Result:

  • Related