@@ -18,7 +18,6 @@ import androidx.compose.runtime.*
1818import androidx.compose.runtime.saveable.rememberSaveable
1919import androidx.compose.ui.Alignment
2020import androidx.compose.ui.Modifier
21- import androidx.compose.ui.draw.drawWithContent
2221import androidx.compose.ui.graphics.Brush
2322import androidx.compose.ui.graphics.Color
2423import androidx.compose.ui.graphics.graphicsLayer
@@ -49,15 +48,25 @@ fun ExpandableHorizontalPager(
4948 targetWidth : Dp = 300.dp,
5049 aspectRatio : Float = 2/3f,
5150 durationMillis : Int = 400,
52- mainContent : @Composable ColumnScope .(page: Int , expanded: Boolean ) -> Unit ,
51+ mainContent : @Composable ColumnScope .(page: Int ) -> Unit ,
5352 overMainContentExpanded : @Composable ColumnScope .(page: Int ) -> Unit ,
5453 overMainContentCollapsed : @Composable ColumnScope .(page: Int ) -> Unit ,
5554 hiddenContentBoxHeight : Dp = Dp .Unspecified ,
5655 hiddenContent : @Composable ColumnScope .(page: Int ) -> Unit
5756) {
58- var expanded by rememberSaveable { mutableStateOf(false ) }
57+ var state by rememberSaveable { mutableStateOf(ExpandablePagerState . INITIAL ) }
5958
60- var isAnimationFinished by remember { mutableStateOf(false ) }
59+ fun animationFinish (expandablePagerState : ExpandablePagerState ) {
60+ when (expandablePagerState) {
61+ ExpandablePagerState .INITIAL_TO_TARGET -> {
62+ state = ExpandablePagerState .TARGET
63+ }
64+ ExpandablePagerState .TARGET_TO_INITIAL -> {
65+ state = ExpandablePagerState .INITIAL
66+ }
67+ else -> {}
68+ }
69+ }
6170
6271 val contentOffSetXState by remember { mutableStateOf(0 .dp) }
6372 val contentOffSetX by animateDpAsState(
@@ -80,7 +89,10 @@ fun ExpandableHorizontalPager(
8089 targetValue = contentWidthState,
8190 animationSpec = tween(
8291 durationMillis = durationMillis
83- )
92+ ),
93+ finishedListener = {
94+ animationFinish(state)
95+ }
8496 )
8597
8698 var boxHeightState by remember { mutableStateOf(0 .dp) }
@@ -99,7 +111,7 @@ fun ExpandableHorizontalPager(
99111 durationMillis = durationMillis
100112 ),
101113 finishedListener = {
102- isAnimationFinished = ! isAnimationFinished
114+ animationFinish(state)
103115 }
104116 )
105117
@@ -108,7 +120,7 @@ fun ExpandableHorizontalPager(
108120 targetValue = cornerSizeState,
109121 animationSpec = tween(
110122 durationMillis = durationMillis
111- )
123+ ),
112124 )
113125
114126 var horizontalPaddingState by remember { mutableStateOf(initialHorizontalPadding) }
@@ -120,7 +132,10 @@ fun ExpandableHorizontalPager(
120132 )
121133
122134 fun expand (maxHeight : Dp ) {
123- if (! expanded) {
135+ if (state == ExpandablePagerState .INITIAL ) {
136+
137+ state = ExpandablePagerState .INITIAL_TO_TARGET
138+
124139 horizontalPaddingState = targetHorizontalPadding
125140
126141 contentWidthState = targetWidth
@@ -139,7 +154,10 @@ fun ExpandableHorizontalPager(
139154 }
140155
141156 cornerSizeState = 0 .dp
142- } else {
157+ } else if (state == ExpandablePagerState .TARGET ) {
158+
159+ state = ExpandablePagerState .TARGET_TO_INITIAL
160+
143161 horizontalPaddingState = initialHorizontalPadding
144162
145163 contentWidthState = initialWidth
@@ -150,7 +168,8 @@ fun ExpandableHorizontalPager(
150168
151169 cornerSizeState = 16 .dp
152170 }
153- expanded = ! expanded
171+
172+
154173 }
155174
156175 HorizontalPager (
@@ -170,15 +189,25 @@ fun ExpandableHorizontalPager(
170189 Card (
171190 modifier = Modifier
172191 .width(contentWidth)
173- .height(if (expanded) boxHeight else 0 .dp)
192+ .height(
193+ if (currentPage == page) {
194+ boxHeight
195+ } else {
196+ if (state == ExpandablePagerState .TARGET ) {
197+ boxHeight
198+ } else {
199+ 0 .dp
200+ }
201+ }
202+ )
174203 .offset(
175204 x = 0 .dp,
176205 y = boxOffSetY
177206 )
178207 .graphicsLayer {
179- if ( ! expanded ) {
208+ if (state != ExpandablePagerState . TARGET ) {
180209 val pageOffset = calculateCurrentOffsetForPage(page).absoluteValue
181- if (outerItemScaleEnabled) {
210+ if (outerItemScaleEnabled) {
182211 lerp(
183212 start = outerItemScale,
184213 stop = 1f ,
@@ -188,7 +217,7 @@ fun ExpandableHorizontalPager(
188217 scaleY = scale
189218 }
190219 }
191- if (outerItemAlphaEnabled) {
220+ if (outerItemAlphaEnabled) {
192221 alpha = lerp(
193222 start = outerItemAlpha,
194223 stop = 1f ,
@@ -205,11 +234,6 @@ fun ExpandableHorizontalPager(
205234 ) {
206235 BoxWithConstraints (
207236 modifier = Modifier
208- .drawWithContent {
209- if (isAnimationFinished) {
210- drawContent()
211- }
212- }
213237 .draggable(
214238 orientation = Orientation .Vertical ,
215239 state = rememberDraggableState {},
@@ -218,7 +242,7 @@ fun ExpandableHorizontalPager(
218242 contentAlignment = Alignment .Center
219243 ) {
220244 Column () {
221- if (expanded ) {
245+ if (state == ExpandablePagerState . TARGET ) {
222246 hiddenContent(page)
223247 }
224248 }
@@ -234,9 +258,9 @@ fun ExpandableHorizontalPager(
234258 y = contentOffSetY
235259 )
236260 .graphicsLayer {
237- if ( ! expanded ) {
261+ if (state != ExpandablePagerState . TARGET ) {
238262 val pageOffset = calculateCurrentOffsetForPage(page).absoluteValue
239- if (outerItemScaleEnabled) {
263+ if (outerItemScaleEnabled) {
240264 lerp(
241265 start = outerItemScale,
242266 stop = 1f ,
@@ -246,7 +270,7 @@ fun ExpandableHorizontalPager(
246270 scaleY = scale
247271 }
248272 }
249- if (outerItemAlphaEnabled) {
273+ if (outerItemAlphaEnabled) {
250274 alpha = lerp(
251275 start = outerItemAlpha,
252276 stop = 1f ,
@@ -272,11 +296,12 @@ fun ExpandableHorizontalPager(
272296 ) {
273297 Box () {
274298 Column () {
275- mainContent(page, expanded )
299+ mainContent(page)
276300 }
277301 Column () {
278302 AnimatedVisibility (
279- visible = ! expanded,
303+ visible = state == ExpandablePagerState .INITIAL ||
304+ state == ExpandablePagerState .TARGET_TO_INITIAL ,
280305 enter = fadeIn(tween(durationMillis)),
281306 exit = fadeOut(tween(durationMillis))
282307 ) {
@@ -301,7 +326,8 @@ fun ExpandableHorizontalPager(
301326 }
302327 Column () {
303328 AnimatedVisibility (
304- visible = expanded,
329+ visible = state == ExpandablePagerState .TARGET ||
330+ state == ExpandablePagerState .INITIAL_TO_TARGET ,
305331 enter = fadeIn(tween(durationMillis)),
306332 exit = fadeOut(tween(durationMillis))
307333 ) {
@@ -328,4 +354,8 @@ fun ExpandableHorizontalPager(
328354 }
329355 }
330356 }
357+ }
358+
359+ enum class ExpandablePagerState {
360+ INITIAL , INITIAL_TO_TARGET , TARGET_TO_INITIAL , TARGET
331361}
0 commit comments