@@ -7,13 +7,14 @@ import androidx.compose.foundation.layout.fillMaxWidth
77import androidx.compose.foundation.layout.height
88import androidx.compose.foundation.layout.padding
99import androidx.compose.foundation.lazy.LazyColumn
10+ import androidx.compose.foundation.lazy.LazyListItemInfo
1011import androidx.compose.material3.Text
1112import androidx.compose.runtime.Composable
1213import androidx.compose.runtime.LaunchedEffect
13- import androidx.compose.runtime.derivedStateOf
1414import androidx.compose.runtime.getValue
1515import androidx.compose.runtime.mutableIntStateOf
1616import androidx.compose.runtime.remember
17+ import androidx.compose.runtime.rememberUpdatedState
1718import androidx.compose.runtime.setValue
1819import androidx.compose.runtime.snapshotFlow
1920import androidx.compose.ui.Alignment
@@ -104,6 +105,14 @@ internal fun <T> PickerItem(
104105 val totalItemHeight = itemHeightDp + style.itemSpacing
105106 val totalItemHeightPx = totalItemHeight.toPx()
106107
108+ val layoutInfo by rememberUpdatedState(listState.layoutInfo)
109+
110+ val itemInfoMap = remember(layoutInfo) {
111+ layoutInfo.visibleItemsInfo.associateBy { it.index }
112+ }
113+
114+ val viewportCenterOffset = layoutInfo.viewportStartOffset + (layoutInfo.viewportEndOffset - layoutInfo.viewportStartOffset) / 2
115+
107116 Box (modifier = modifier) {
108117 LazyColumn (
109118 state = listState,
@@ -115,20 +124,6 @@ internal fun <T> PickerItem(
115124 .pointerInput(Unit ) { detectVerticalDragGestures { change, _ -> change.consume() } }
116125 ) {
117126 items(listScrollCount, key = { index -> index }) { index ->
118- val layoutInfo by remember { derivedStateOf { listState.layoutInfo } }
119-
120- val viewportCenterOffset = layoutInfo.viewportStartOffset +
121- (layoutInfo.viewportEndOffset - layoutInfo.viewportStartOffset) / 2
122-
123- val itemInfo = layoutInfo.visibleItemsInfo.find { it.index == index }
124- val itemCenterOffset = itemInfo?.offset?.let { it + (itemInfo.size / 2 ) } ? : 0
125-
126- val distanceFromCenter = abs(viewportCenterOffset - itemCenterOffset).toFloat()
127- val maxDistance = totalItemHeightPx * visibleItemsMiddle
128-
129- val alpha = curveEffect.calculateAlpha(distanceFromCenter, maxDistance)
130- val scaleY = curveEffect.calculateScaleY(distanceFromCenter, maxDistance)
131-
132127 val item = getItemForIndex(
133128 index = index,
134129 items = items,
@@ -140,11 +135,17 @@ internal fun <T> PickerItem(
140135 text = item?.let { itemFormatter(it) } ? : " " ,
141136 maxLines = 1 ,
142137 style = style.textStyle,
143- color = style.textColor.copy(alpha = alpha) ,
138+ color = style.textColor,
144139 modifier = Modifier
145140 .padding(vertical = style.itemSpacing / 2 )
146- .graphicsLayer(scaleY = scaleY)
147- .onSizeChanged { size -> itemHeightPixels = size.height }
141+ .curvedPickerEffect(
142+ index = index,
143+ viewportCenterOffset = viewportCenterOffset,
144+ itemInfoMap = itemInfoMap,
145+ totalItemHeightPx = totalItemHeightPx,
146+ visibleItemsMiddle = visibleItemsMiddle,
147+ curveEffect = curveEffect
148+ ).onSizeChanged { size -> itemHeightPixels = size.height }
148149 .then(textModifier)
149150 )
150151 }
@@ -180,6 +181,27 @@ private fun getStartIndexForInfiniteScroll(
180181 return listScrollMiddle - listScrollMiddle % itemSize - visibleItemsMiddle + startIndex
181182}
182183
184+ fun Modifier.curvedPickerEffect (
185+ index : Int ,
186+ viewportCenterOffset : Int ,
187+ itemInfoMap : Map <Int , LazyListItemInfo >,
188+ totalItemHeightPx : Float ,
189+ visibleItemsMiddle : Int ,
190+ curveEffect : CurveEffect
191+ ): Modifier = graphicsLayer {
192+ val itemInfo = itemInfoMap[index]
193+ val itemCenterOffset = itemInfo?.let { it.offset + (it.size / 2 ) } ? : 0
194+
195+ val distanceFromCenter = abs(viewportCenterOffset - itemCenterOffset).toFloat()
196+ val maxDistance = totalItemHeightPx * visibleItemsMiddle
197+
198+ val alpha = curveEffect.calculateAlpha(distanceFromCenter, maxDistance)
199+ val scaleY = curveEffect.calculateScaleY(distanceFromCenter, maxDistance)
200+
201+ this .alpha = alpha
202+ this .scaleY = scaleY
203+ }
204+
183205@Composable
184206@Preview
185207private fun PickerItemPreview () {
0 commit comments