@@ -36,7 +36,6 @@ import androidx.compose.material.Text
36
36
import androidx.compose.material.icons.Icons
37
37
import androidx.compose.material.icons.filled.Check
38
38
import androidx.compose.runtime.Composable
39
- import androidx.compose.runtime.SideEffect
40
39
import androidx.compose.runtime.getValue
41
40
import androidx.compose.runtime.mutableStateOf
42
41
import androidx.compose.runtime.remember
@@ -64,65 +63,60 @@ fun MailItem(
64
63
state : MailItemState = MailItemState (-1) { _, _ -> },
65
64
info : MailEntryInfo ?
66
65
) {
67
- val shouldAnimate = remember { info == null }
68
- var csTarget: String? by remember { mutableStateOf(null ) }
66
+ val csTarget: MotionMailState =
67
+ when {
68
+ info == null -> MotionMailState .Loading
69
+ state.isSelected -> MotionMailState .Selected
70
+ else -> MotionMailState .Normal
71
+ }
69
72
MotionLayoutMail (
70
73
modifier = modifier,
71
74
info = info ? : MailEntryInfo .Default ,
72
- startsEmpty = shouldAnimate,
73
- targetId = csTarget,
75
+ targetState = csTarget,
74
76
onSelectedMail = {
77
+ // Toggle selection
75
78
state.setSelected(! state.isSelected)
76
79
}
77
80
)
78
- if (shouldAnimate) {
79
- if (info != null && csTarget == null ) {
80
- SideEffect {
81
- csTarget = " normal"
82
- }
83
- }
84
- } else {
85
- if (info != null ) {
86
- val nextState = if (state.isSelected) {
87
- " flipped"
88
- } else {
89
- " normal"
90
- }
91
- SideEffect {
92
- csTarget = nextState
93
- }
94
- }
95
- }
96
81
}
97
82
98
83
const val ANIMATION_DURATION : Int = 400
99
84
85
+ enum class MotionMailState (val tag : String ) {
86
+ Loading (" empty" ),
87
+ Normal (" normal" ),
88
+ Selected (" flipped" )
89
+ }
90
+
100
91
@Suppress(" NOTHING_TO_INLINE" , " EXPERIMENTAL_API_USAGE" )
101
92
@Composable
102
93
inline fun MotionLayoutMail (
103
94
modifier : Modifier = Modifier ,
104
95
info : MailEntryInfo ,
105
- startsEmpty : Boolean ,
106
- targetId : String? ,
96
+ targetState : MotionMailState ,
107
97
crossinline onSelectedMail : (id: Int ) -> Unit
108
98
) {
109
99
val backgroundColor by animateColorAsState(
110
- targetValue = if (targetId == " flipped" ) {
111
- MaterialTheme .colors.textBackgroundColor
112
- } else {
113
- MaterialTheme .colors.background
100
+ targetValue = when (targetState) {
101
+ MotionMailState .Selected -> MaterialTheme .colors.textBackgroundColor
102
+ else -> MaterialTheme .colors.background
114
103
},
115
104
animationSpec = tween<Color >(ANIMATION_DURATION )
116
105
)
117
- val startId = if (startsEmpty) " empty" else " normal"
118
- val endId = if (startsEmpty) " normal" else " empty"
106
+ val initialStart = remember { targetState }
107
+ val initialEnd = remember {
108
+ when (initialStart) {
109
+ MotionMailState .Loading -> MotionMailState .Normal
110
+ else -> MotionMailState .Loading
111
+ }
112
+ }
119
113
120
- val motionSceneContent = remember(startId, endId) {
114
+ val motionSceneContent = remember {
121
115
// language=json5
122
116
"""
123
117
{
124
118
ConstraintSets: {
125
- normal : {
119
+ ${ MotionMailState . Normal .tag} : {
126
120
picture: {
127
121
width: 60, height: 60,
128
122
centerVertically: 'parent',
@@ -146,8 +140,8 @@ inline fun MotionLayoutMail(
146
140
end: ['parent', 'start', 32]
147
141
}
148
142
},
149
- flipped : {
150
- Extends: 'normal ',
143
+ ${ MotionMailState . Selected .tag} : {
144
+ Extends: '${ MotionMailState . Normal .tag} ',
151
145
picture: {
152
146
rotationY: -180,
153
147
alpha: 0.0
@@ -157,7 +151,7 @@ inline fun MotionLayoutMail(
157
151
alpha: 1.0
158
152
}
159
153
},
160
- empty : {
154
+ ${ MotionMailState . Loading .tag} : {
161
155
picture: {
162
156
width: 60, height: 60,
163
157
top: ['content', 'top', 0],
@@ -183,12 +177,12 @@ inline fun MotionLayoutMail(
183
177
},
184
178
Transitions: {
185
179
default: {
186
- from: '$startId ',
187
- to: '$endId ',
180
+ from: '${initialStart.tag} ',
181
+ to: '${initialEnd.tag} ',
188
182
},
189
183
flip: {
190
- from: 'normal ',
191
- to: 'flipped ',
184
+ from: '${ MotionMailState . Normal .tag} ',
185
+ to: '${ MotionMailState . Selected .tag} ',
192
186
KeyFrames: {
193
187
KeyAttributes: [
194
188
{
@@ -212,7 +206,7 @@ inline fun MotionLayoutMail(
212
206
.fillMaxSize()
213
207
.clip(RectangleShape )
214
208
.padding(8 .dp),
215
- constraintSetName = targetId ,
209
+ constraintSetName = targetState.tag ,
216
210
animationSpec = tween<Float >(ANIMATION_DURATION ),
217
211
motionScene = MotionScene (content = motionSceneContent)
218
212
) {
@@ -241,7 +235,7 @@ inline fun MotionLayoutMail(
241
235
modifier = Modifier .layoutId(" loading" ),
242
236
contentAlignment = Alignment .Center
243
237
) {
244
- // TODO: Find a good way of not composing this when animation ends
238
+ // TODO: Find a way of not composing this (or stop the animation) when transition ends
245
239
CircularProgressIndicator (
246
240
modifier = Modifier .size(40 .dp)
247
241
)
0 commit comments