Skip to content

Commit be958fc

Browse files
committed
AnimatableLazyColumn.kt
1 parent a0cd680 commit be958fc

File tree

2 files changed

+180
-1
lines changed

2 files changed

+180
-1
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package com.commandiron.animatable_compose
2+
3+
import androidx.compose.foundation.gestures.FlingBehavior
4+
import androidx.compose.foundation.gestures.ScrollableDefaults
5+
import androidx.compose.foundation.layout.*
6+
import androidx.compose.foundation.lazy.LazyColumn
7+
import androidx.compose.foundation.lazy.LazyListScope
8+
import androidx.compose.foundation.lazy.LazyListState
9+
import androidx.compose.foundation.lazy.rememberLazyListState
10+
import androidx.compose.runtime.Composable
11+
import androidx.compose.ui.Alignment
12+
import androidx.compose.ui.Modifier
13+
import androidx.compose.ui.unit.Dp
14+
import androidx.compose.ui.unit.DpOffset
15+
import androidx.compose.ui.unit.DpSize
16+
import androidx.compose.ui.unit.dp
17+
import com.commandiron.animatable_compose.state.AnimatableState
18+
import com.commandiron.animatable_compose.state.AnimatableStateTag
19+
import com.commandiron.animatable_compose.state.SharedAnimatableState
20+
21+
@Composable
22+
fun AnimatableLazyColumn(
23+
modifier: Modifier = Modifier,
24+
lazyListState: LazyListState = rememberLazyListState(),
25+
contentPadding: PaddingValues = PaddingValues(0.dp),
26+
reverseLayout: Boolean = false,
27+
verticalArrangement: Arrangement.Vertical =
28+
if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
29+
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
30+
flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
31+
userScrollEnabled: Boolean = true,
32+
state: AnimatableState,
33+
fixedWidth: Dp = Dp.Unspecified,
34+
fixedHeight: Dp = Dp.Unspecified,
35+
fixedOffset: DpOffset = DpOffset.Unspecified,
36+
content: LazyListScope.() -> Unit
37+
) {
38+
LazyColumn(
39+
modifier = Modifier
40+
.width(
41+
when (fixedWidth) {
42+
Dp.Unspecified -> if (state.animatedSize == DpSize.Unspecified) {
43+
Dp.Unspecified
44+
} else state.animatedSize.width
45+
Dp.Infinity -> state.screenWidth
46+
else -> fixedWidth
47+
}
48+
)
49+
.height(
50+
when (fixedHeight) {
51+
Dp.Unspecified -> if (state.animatedSize == DpSize.Unspecified) {
52+
Dp.Unspecified
53+
} else state.animatedSize.height
54+
Dp.Infinity -> state.screenHeight
55+
else -> fixedHeight
56+
}
57+
)
58+
.offset(
59+
x = when (fixedOffset) {
60+
DpOffset.Unspecified -> state.animatedOffset.x
61+
else -> fixedOffset.x
62+
},
63+
y = when (fixedOffset) {
64+
DpOffset.Unspecified -> state.animatedOffset.y
65+
else -> fixedOffset.y
66+
}
67+
)
68+
.then(modifier),
69+
state = lazyListState,
70+
contentPadding = contentPadding,
71+
reverseLayout = reverseLayout,
72+
verticalArrangement = verticalArrangement,
73+
horizontalAlignment = horizontalAlignment,
74+
flingBehavior = flingBehavior,
75+
userScrollEnabled = userScrollEnabled,
76+
content = content
77+
)
78+
}
79+
80+
@Composable
81+
fun AnimatableLazyColumn(
82+
modifier: Modifier = Modifier,
83+
lazyListState: LazyListState = rememberLazyListState(),
84+
contentPadding: PaddingValues = PaddingValues(0.dp),
85+
reverseLayout: Boolean = false,
86+
verticalArrangement: Arrangement.Vertical =
87+
if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,
88+
horizontalAlignment: Alignment.Horizontal = Alignment.Start,
89+
flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),
90+
userScrollEnabled: Boolean = true,
91+
state: SharedAnimatableState,
92+
stateIndex: Int = 0,
93+
fixedWidth: Dp = Dp.Unspecified,
94+
fixedHeight: Dp = Dp.Unspecified,
95+
fixedOffset: DpOffset = DpOffset.Unspecified,
96+
content: LazyListScope.() -> Unit
97+
) {
98+
val stateIn = state.getState(AnimatableStateTag.LAZY_COLUMN, stateIndex) ?: throw (
99+
IllegalArgumentException("no animatableState has this index: $stateIndex")
100+
)
101+
LazyColumn(
102+
modifier = Modifier
103+
.width(
104+
when (fixedWidth) {
105+
Dp.Unspecified -> if (stateIn.animatedSize == DpSize.Unspecified) {
106+
Dp.Unspecified
107+
} else stateIn.animatedSize.width
108+
Dp.Infinity -> stateIn.screenWidth
109+
else -> fixedWidth
110+
}
111+
)
112+
.height(
113+
when (fixedHeight) {
114+
Dp.Unspecified -> if (stateIn.animatedSize == DpSize.Unspecified) {
115+
Dp.Unspecified
116+
} else stateIn.animatedSize.height
117+
Dp.Infinity -> stateIn.screenHeight
118+
else -> fixedHeight
119+
}
120+
)
121+
.offset(
122+
x = when (fixedOffset) {
123+
DpOffset.Unspecified -> stateIn.animatedOffset.x
124+
else -> fixedOffset.x
125+
},
126+
y = when (fixedOffset) {
127+
DpOffset.Unspecified -> stateIn.animatedOffset.y
128+
else -> fixedOffset.y
129+
}
130+
)
131+
.then(modifier),
132+
state = lazyListState,
133+
contentPadding = contentPadding,
134+
reverseLayout = reverseLayout,
135+
verticalArrangement = verticalArrangement,
136+
horizontalAlignment = horizontalAlignment,
137+
flingBehavior = flingBehavior,
138+
userScrollEnabled = userScrollEnabled,
139+
content = content
140+
)
141+
}

animatable-compose/src/main/java/com/commandiron/animatable_compose/state/AnimatableState.kt

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ enum class AnimationState {
907907
}
908908

909909
enum class AnimatableStateTag {
910-
SPACER, TEXT, BOX, CARD, ICON, LAZY_ROW,
910+
SPACER, TEXT, BOX, CARD, ICON, LAZY_ROW, LAZY_COLUMN,
911911
}
912912

913913
@Composable
@@ -1200,4 +1200,42 @@ fun rememberAnimatableLazyRowState(
12001200
onAnimation = onAnimation
12011201
)
12021202
}
1203+
}
1204+
1205+
@Composable
1206+
fun rememberAnimatableLazyColumnState(
1207+
index: Int = 0,
1208+
initialSize: DpSize? = null,
1209+
targetSize: DpSize? = null,
1210+
toTargetSizeAnimationSpec: AnimationSpec<Size>? = null,
1211+
toInitialSizeAnimationSpec: AnimationSpec<Size>? = null,
1212+
onSizeAnimation: (AnimationState) -> Unit = {},
1213+
initialOffset: DpOffset? = null,
1214+
targetOffset: DpOffset? = null,
1215+
toTargetOffsetAnimationSpec: AnimationSpec<Size>? = null,
1216+
toInitialOffsetAnimationSpec: AnimationSpec<Size>? = null,
1217+
onOffsetAnimation: (AnimationState) -> Unit = {},
1218+
toTargetAnimationSpec: AnimationSpec<Float>? = tween(500),
1219+
toInitialAnimationSpec: AnimationSpec<Float>? = tween(500),
1220+
onAnimation: (AnimationState) -> Unit = {}
1221+
): AnimatableState {
1222+
return remember {
1223+
AnimatableState(
1224+
animatableStateTag = AnimatableStateTag.LAZY_COLUMN,
1225+
index = index,
1226+
initialSize = initialSize,
1227+
targetSize = targetSize,
1228+
toTargetSizeAnimationSpec = toTargetSizeAnimationSpec,
1229+
toInitialSizeAnimationSpec = toInitialSizeAnimationSpec,
1230+
onSizeAnimation = onSizeAnimation,
1231+
initialOffset = initialOffset,
1232+
targetOffset = targetOffset,
1233+
toTargetOffsetAnimationSpec = toTargetOffsetAnimationSpec,
1234+
toInitialOffsetAnimationSpec = toInitialOffsetAnimationSpec,
1235+
onOffsetAnimation = onOffsetAnimation,
1236+
toTargetAnimationSpec = toTargetAnimationSpec,
1237+
toInitialAnimationSpec = toInitialAnimationSpec,
1238+
onAnimation = onAnimation
1239+
)
1240+
}
12031241
}

0 commit comments

Comments
 (0)