extract the artist grid scroll estimate and test it

The index to pixel arithmetic was inline and fiddly (it was missing the row gap), so pull it
out as estimateScrollPx and pin the 2-column cases. ROW_GAP is shared with the grid spacing.
This commit is contained in:
austinried
2026-10-04 00:29:59 +00:00
parent 8d8c8be2a8
commit 7af87d63d9
2 changed files with 54 additions and 9 deletions
@@ -82,6 +82,21 @@ import org.koin.core.parameter.parametersOf
private val ART_HEIGHT = 420.dp
private val TITLE_INSET = 16.dp
private val ROW_GAP = 16.dp
internal fun estimateScrollPx(
index: Int,
offset: Float,
imageHeightPx: Float,
albumHeightPx: Float,
albumRowGapPx: Float,
): Float =
if (index <= 0) {
offset
} else {
imageHeightPx + albumRowGapPx + (albumHeightPx + albumRowGapPx) * ((index - 1) / 2) + offset
}
private val FADE_LEAD = 24.dp
private const val THEME_TRANSITION_MS = 100
private const val SCRIM_FADE_MS = 180
@@ -164,16 +179,16 @@ fun ArtistDetailScreen(
}
var imageHeightPx by remember { mutableFloatStateOf(0f) }
var albumHeightPx by remember { mutableFloatStateOf(0f) }
val albumRowGapPx = with(density) { 16.dp.toPx() }
val albumRowGapPx = with(density) { ROW_GAP.toPx() }
val scrollPx by remember {
derivedStateOf {
val index = listState.firstVisibleItemIndex
val offset = listState.firstVisibleItemScrollOffset.toFloat()
if (index <= 0) {
offset
} else {
imageHeightPx + albumRowGapPx + (albumHeightPx + albumRowGapPx) * ((index - 1) / 2) + offset
}
estimateScrollPx(
index = listState.firstVisibleItemIndex,
offset = listState.firstVisibleItemScrollOffset.toFloat(),
imageHeightPx = imageHeightPx,
albumHeightPx = albumHeightPx,
albumRowGapPx = albumRowGapPx,
)
}
}
val nameTextStyle = MaterialTheme.typography.headlineLarge
@@ -207,7 +222,7 @@ fun ArtistDetailScreen(
columns = GridCells.Fixed(2),
contentPadding = PaddingValues(bottom = 16.dp + navBarBottom),
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(ROW_GAP),
modifier = Modifier.fillMaxSize(),
) {
item(span = { GridItemSpan(maxLineSpan) }) {
@@ -0,0 +1,30 @@
package com.subtracks.ui.library
import org.junit.Assert.assertEquals
import org.junit.Test
class EstimateScrollPxTest {
private val image = 432f
private val album = 200f
private val gap = 16f
@Test
fun theHeroUsesTheRawOffset() {
assertEquals(50f, estimateScrollPx(0, 50f, image, album, gap), 0.01f)
}
@Test
fun theFirstAlbumRowAddsTheHeroAndOneGap() {
assertEquals(image + gap + 10f, estimateScrollPx(1, 10f, image, album, gap), 0.01f)
}
@Test
fun theSecondCellOfARowDoesNotAdvance() {
assertEquals(estimateScrollPx(1, 10f, image, album, gap), estimateScrollPx(2, 10f, image, album, gap), 0.01f)
}
@Test
fun theNextRowAddsACellAndAGap() {
assertEquals(image + gap + (album + gap) + 10f, estimateScrollPx(3, 10f, image, album, gap), 0.01f)
}
}