Hiding the Top of the Screen When Scrolling Down in a List

Murat Gunay
2 min readSep 3, 2024

--

I first saw that feature on Twitter App, and I liked it. I’ve noticed that many apps don’t have this feature, which I think is a flaw in UI design for usability. You can see my example below, and then I will explain how you can achieve it.

First, define required variables to control the animation.

    // State to keep track of the scroll position
val scrollState = rememberLazyListState()

// Determine the scroll offset in pixels
val scrollOffset by remember {
derivedStateOf { scrollState.firstVisibleItemScrollOffset }
}

val firstVisibleItemIndex by remember {
derivedStateOf { scrollState.firstVisibleItemIndex }
}

// Set the maximum height for the header
val maxHeight = 170.dp // Adjust this to your desired maximum height
val minHeight = 0.dp // Minimum height (collapsed)

// Calculate the height of the header dynamically based on scroll position
val headerHeight = remember(firstVisibleItemIndex, scrollOffset) {
when {
firstVisibleItemIndex > 1 -> minHeight // After scrolling past the second item, header stays collapsed
firstVisibleItemIndex == 1 -> max(minHeight.value, maxHeight.value - scrollOffset.toFloat()).dp
else -> maxHeight // Header is fully expanded before the second item is visible
}
}

// Determine the alpha for the header fade-out effect
val headerAlpha = if (headerHeight > minHeight) {
min(1f, headerHeight.value / maxHeight.value)
} else {
0f
}

Then, for top side section;

//This part included in the main UI part.
ProfileHeaderSection(
height = headerHeight,
alpha = headerAlpha
)


//Section is define seperately and used in the main part like above
@Composable
fun ProfileHeaderSection(height: Dp, alpha: Float) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.height(height)
.graphicsLayer(
alpha = alpha
)
) {
//Content goes here.....


}
}

For the content part that includes list of items:

//This part included in the main UI part
ContentSection(scrollState = scrollState)

//This is a separate section for the content part and used in mian UI like above
@Composable
fun ContentSection(scrollState: LazyListState) {

LazyColumn(modifier = Modifier.background(ColorBackground),
contentPadding = PaddingValues(10.dp),
state = scrollState
) {
//Content of list item goes here...
}
}

This is the implementation of that feature. Code talks itself. No need to explain it more.

Happy coding...

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Murat Gunay
Murat Gunay

No responses yet

Write a response