Skip to content
This repository was archived by the owner on Dec 27, 2024. It is now read-only.

Commit cf30944

Browse files
committed
ComposeMail - Improve MailItem composition logic
1 parent eee863b commit cf30944

File tree

4 files changed

+43
-47
lines changed

4 files changed

+43
-47
lines changed

demoProjects/ComposeMail/app/src/main/java/com/example/composemail/ui/components/CheapText.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,17 @@ private fun CheapTextPreview() {
6060
Column(
6161
Modifier
6262
.width(40.dp)
63-
.background(Color.LightGray)) {
63+
.background(Color.LightGray)
64+
) {
6465
Text(text = "Hello \nWorld!")
6566
Text(text = "This is a very very long text")
6667
}
6768
Text(text = "Cheap")
6869
Column(
6970
Modifier
7071
.width(40.dp)
71-
.background(Color.LightGray)) {
72+
.background(Color.LightGray)
73+
) {
7274
CheapText(text = "Hello \nWorld!")
7375
CheapText(text = "This is a very very long text")
7476
}

demoProjects/ComposeMail/app/src/main/java/com/example/composemail/ui/mails/MailItem.kt

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import androidx.compose.material.Text
3636
import androidx.compose.material.icons.Icons
3737
import androidx.compose.material.icons.filled.Check
3838
import androidx.compose.runtime.Composable
39-
import androidx.compose.runtime.SideEffect
4039
import androidx.compose.runtime.getValue
4140
import androidx.compose.runtime.mutableStateOf
4241
import androidx.compose.runtime.remember
@@ -64,65 +63,60 @@ fun MailItem(
6463
state: MailItemState = MailItemState(-1) { _, _ -> },
6564
info: MailEntryInfo?
6665
) {
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+
}
6972
MotionLayoutMail(
7073
modifier = modifier,
7174
info = info ?: MailEntryInfo.Default,
72-
startsEmpty = shouldAnimate,
73-
targetId = csTarget,
75+
targetState = csTarget,
7476
onSelectedMail = {
77+
// Toggle selection
7578
state.setSelected(!state.isSelected)
7679
}
7780
)
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-
}
9681
}
9782

9883
const val ANIMATION_DURATION: Int = 400
9984

85+
enum class MotionMailState(val tag: String) {
86+
Loading("empty"),
87+
Normal("normal"),
88+
Selected("flipped")
89+
}
90+
10091
@Suppress("NOTHING_TO_INLINE", "EXPERIMENTAL_API_USAGE")
10192
@Composable
10293
inline fun MotionLayoutMail(
10394
modifier: Modifier = Modifier,
10495
info: MailEntryInfo,
105-
startsEmpty: Boolean,
106-
targetId: String?,
96+
targetState: MotionMailState,
10797
crossinline onSelectedMail: (id: Int) -> Unit
10898
) {
10999
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
114103
},
115104
animationSpec = tween<Color>(ANIMATION_DURATION)
116105
)
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+
}
119113

120-
val motionSceneContent = remember(startId, endId) {
114+
val motionSceneContent = remember {
121115
//language=json5
122116
"""
123117
{
124118
ConstraintSets: {
125-
normal: {
119+
${MotionMailState.Normal.tag}: {
126120
picture: {
127121
width: 60, height: 60,
128122
centerVertically: 'parent',
@@ -146,8 +140,8 @@ inline fun MotionLayoutMail(
146140
end: ['parent', 'start', 32]
147141
}
148142
},
149-
flipped: {
150-
Extends: 'normal',
143+
${MotionMailState.Selected.tag}: {
144+
Extends: '${MotionMailState.Normal.tag}',
151145
picture: {
152146
rotationY: -180,
153147
alpha: 0.0
@@ -157,7 +151,7 @@ inline fun MotionLayoutMail(
157151
alpha: 1.0
158152
}
159153
},
160-
empty: {
154+
${MotionMailState.Loading.tag}: {
161155
picture: {
162156
width: 60, height: 60,
163157
top: ['content', 'top', 0],
@@ -183,12 +177,12 @@ inline fun MotionLayoutMail(
183177
},
184178
Transitions: {
185179
default: {
186-
from: '$startId',
187-
to: '$endId',
180+
from: '${initialStart.tag}',
181+
to: '${initialEnd.tag}',
188182
},
189183
flip: {
190-
from: 'normal',
191-
to: 'flipped',
184+
from: '${MotionMailState.Normal.tag}',
185+
to: '${MotionMailState.Selected.tag}',
192186
KeyFrames: {
193187
KeyAttributes: [
194188
{
@@ -212,7 +206,7 @@ inline fun MotionLayoutMail(
212206
.fillMaxSize()
213207
.clip(RectangleShape)
214208
.padding(8.dp),
215-
constraintSetName = targetId,
209+
constraintSetName = targetState.tag,
216210
animationSpec = tween<Float>(ANIMATION_DURATION),
217211
motionScene = MotionScene(content = motionSceneContent)
218212
) {
@@ -241,7 +235,7 @@ inline fun MotionLayoutMail(
241235
modifier = Modifier.layoutId("loading"),
242236
contentAlignment = Alignment.Center
243237
) {
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
245239
CircularProgressIndicator(
246240
modifier = Modifier.size(40.dp)
247241
)

demoProjects/ComposeMail/app/src/main/java/com/example/composemail/ui/mails/MailItemState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package com.example.composemail.ui.mails
1818

1919
import androidx.compose.runtime.mutableStateOf
2020

21-
class MailItemState(val id: Int, private val onSelected: (Int, Boolean) -> Unit) {
21+
class MailItemState(val id: Int, private val onSelected: (id: Int, isSelected: Boolean) -> Unit) {
2222
private val _isSelected = mutableStateOf(false)
2323
val isSelected
2424
get() = _isSelected.value

demoProjects/ComposeMail/app/src/main/java/com/example/composemail/ui/newmail/NewMailState.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ import androidx.compose.runtime.remember
2323
@Suppress("NOTHING_TO_INLINE")
2424
@Composable
2525
inline fun rememberNewMailState(
26-
vararg keys: Any? = arrayOf(Unit),
26+
key: Any = Unit,
2727
initialLayoutState: NewMailLayoutState
2828
): NewMailState {
29-
return remember(*keys) { NewMailState(initialLayoutState) }
29+
return remember(key) { NewMailState(initialLayoutState) }
3030
}
3131

3232
class NewMailState(initialLayoutState: NewMailLayoutState) {

0 commit comments

Comments
 (0)