Skip to content

Commit cdc1d41

Browse files
authored
Animate follow icon rotation in Jetcaster (#1603)
### Overview This PR adds a small rotation animation to the "Follow" icon in the Jetcaster app to improve visual feedback when toggling follow/unfollow. This implements the TODO found in FollowButton.kt: `// TODO: think about animating these icons` ### What Changed - Added an `animateFloatAsState` to animate icon rotation from 0f to 360f when `isFollowed` changes - Applied `Modifier.rotate()` to the Icon based on the animated value ### Why This small UX enhancement helps to make the follow action feel more responsive and polished visually for users. ### How it looks like (example screen recording) ![Screen_recording_20250818_202230](https://github.com/user-attachments/assets/0ad3d09a-decf-479b-8c53-2672db335894) Let me know if any adjustments are needed. 🙂
2 parents 38a1e4e + 9544201 commit cdc1d41

File tree

1 file changed

+25
-1
lines changed
  • Jetcaster/mobile/src/main/java/com/example/jetcaster/util

1 file changed

+25
-1
lines changed

Jetcaster/mobile/src/main/java/com/example/jetcaster/util/Buttons.kt

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
package com.example.jetcaster.util
1818

19+
import androidx.compose.animation.core.animateFloat
20+
import androidx.compose.animation.core.snap
21+
import androidx.compose.animation.core.spring
22+
import androidx.compose.animation.core.updateTransition
1923
import androidx.compose.foundation.shape.CircleShape
2024
import androidx.compose.foundation.shape.RoundedCornerShape
2125
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
@@ -25,7 +29,9 @@ import androidx.compose.material3.IconToggleButtonColors
2529
import androidx.compose.material3.IconToggleButtonShapes
2630
import androidx.compose.material3.MaterialTheme
2731
import androidx.compose.runtime.Composable
32+
import androidx.compose.runtime.getValue
2833
import androidx.compose.ui.Modifier
34+
import androidx.compose.ui.draw.rotate
2935
import androidx.compose.ui.res.painterResource
3036
import androidx.compose.ui.res.stringResource
3137
import androidx.compose.ui.unit.dp
@@ -52,8 +58,25 @@ fun ToggleFollowPodcastIconButton(isFollowed: Boolean, onClick: () -> Unit, modi
5258
checkedShape = CircleShape,
5359
),
5460
) {
61+
val transition = updateTransition(targetState = isFollowed, label = "FollowToggle")
62+
val iconRotation by transition.animateFloat(
63+
label = "IconRotation",
64+
transitionSpec = {
65+
if (initialState == targetState) {
66+
snap()
67+
} else {
68+
spring(
69+
dampingRatio = 0.6f,
70+
stiffness = 200f,
71+
)
72+
}
73+
},
74+
) { followed ->
75+
if (followed) 360f else 0f
76+
}
77+
5578
Icon(
56-
// TODO: think about animating these icons
79+
// Animated rotation when follow state changes
5780
painter = when {
5881
isFollowed -> painterResource(id = R.drawable.ic_check)
5982
else -> painterResource(id = R.drawable.ic_add)
@@ -62,6 +85,7 @@ fun ToggleFollowPodcastIconButton(isFollowed: Boolean, onClick: () -> Unit, modi
6285
isFollowed -> stringResource(R.string.cd_following)
6386
else -> stringResource(R.string.cd_not_following)
6487
},
88+
modifier = Modifier.rotate(iconRotation),
6589
)
6690
}
6791
}

0 commit comments

Comments
 (0)