How to Create an Animated Strikethrough Text in Jetpack Compose
Kappdev on 2024-02-23
How to Create an Animated Strikethrough Text in Jetpack Compose
Welcome πββοΈ
In this article, weβll create an Animated Strikethrough Text with Jetpack Compose.
This simple yet captivating animation might bring life into your UI.
Especially when combined with checkboxes β
Letβs dive in together π

Defining the Function
Letβs begin by crafting the AnimatedStrikethroughText
composable function:
@Composable fun AnimatedStrikethroughText( text: String, modifier: Modifier = Modifier, isVisible: Boolean = true, animateOnHide: Boolean = true, spec: AnimationSpec<Int> = tween(text.length * 30, easing = FastOutLinearInEasing), strikethroughStyle: SpanStyle = SpanStyle(), textStyle: TextStyle = LocalTextStyle.current )
Parameters
β
text
π The text to be displayed with the animated strikethrough effect.
β
modifier
π The Modifier
to be applied to the Text
composable.
β
isVisible
π Determines whether the strikethrough effect should be visible or not.
β
animateOnHide
π Determines whether the animation should be played when hiding the strikethrough effect (isVisible
set to false
).
β
spec
π Specifies animation specifications. By default, it uses FastOutLinearInEasing
, with duration proportional to the text length
.
β
strikethroughStyle
π Defines the style of the effect. It allows you to customize the effect and apply not only strikethrough but all the styles supported by SpanStyle
.
β
textStyle
π Defines the style of the text. The default value is set to the current local text style.
Implementation
With the function signature defined, letβs proceed to implement the function and bring our animation to life β¨
Utility Function
Before we begin the implementation, letβs encapsulate the logic for building an AnnotatedString
into a separate utility function:
fun String.buildStrikethrough(length: Int, style: SpanStyle) = buildAnnotatedString { append(this@buildStrikethrough) val strikethroughStyle = style.copy(textDecoration = TextDecoration.LineThrough) addStyle(strikethroughStyle, 0, length) }
Defining Variables
To implement the animation, we need to define two variables:
1οΈβ£ textToDisplay
: A mutable state that holds a styled AnnotatedString
to be displayed
var textToDisplay by remember { mutableStateOf(AnnotatedString("")) }
2οΈβ£ length
: An Animatable
state that holds the length of the text to be affected
val length = remember { Animatable(initialValue = 0, typeConverter = Int.VectorConverter) }
Updating Text Effect
When the length
changes, we need to update the textToDisplay
variable with the corresponding strikethrough length:
LaunchedEffect(length.value) { textToDisplay = text.buildStrikethrough(length.value, strikethroughStyle) }
Triggering the Animation
When the visibility (isVisible
) changes, we initiate the appropriate animation:
LaunchedEffect(isVisible) { when { isVisible -> length.animateTo(text.length, spec) !isVisible && animateOnHide -> length.animateTo(0, spec) else -> length.snapTo(0) } }
Updating Text
When the text changes, textToDisplay
has to be updated depending on isVisible
and the length of the text:
LaunchedEffect(text) { when { isVisible && text.length == length.value -> { textToDisplay = text.buildStrikethrough(length.value, strikethroughStyle) } isVisible && text.length != length.value -> { length.snapTo(text.length) } else -> textToDisplay = AnnotatedString(text) } }
Rendering the Text
Finally, we have to render the text with the appropriate textToDisplay
, modifier
, and style
:
Text( text = textToDisplay, modifier = modifier, style = textStyle )
Congratulations π₯³! Weβve successfully built it π. You can find the full code on GitHub Gist π§βπ». Letβs explore the usage π

Practical Usage πββοΈ
For the sake of example, letβs create a list of to-do items featuring checkboxes
and the AnimatedStrikethroughText
.
First, letβs start by defining the TodoItem
component:
@Composable fun TodoItem( text: String, checked: Boolean, modifier: Modifier = Modifier, onCheckedChange: (Boolean) -> Unit ) { Row( modifier = modifier, verticalAlignment = Alignment.CenterVertically ) { Checkbox( checked = checked, onCheckedChange = onCheckedChange ) AnimatedStrikethroughText( text = text, isVisible = checked, strikethroughStyle = SpanStyle( color = Color.Black.copy(0.32f) ) ) } }
Next, letβs define a list of to-do items:
val Tasks = listOf( "Grab a coffee", "Find a comfy spot", "Write some code" )
The final touch is to place those to-do items into a Column
:
Column { Tasks.forEach { task -> var checked by remember { mutableStateOf(false) } TodoItem( text = task, checked = checked, onCheckedChange = { checked = it } ) } }
Output π


How to Create a Rainbow Loader Animation in Jetpack Compose Welcome π In this article, weβll build an amazing Rainbow Loader Animation in Jetpack Compose in less than 5 minutesβ¦medium.com
Thank you for reading this article! β€οΈ If you found it enjoyable and valuable, show your appreciation by clapping π and following Kappdev for more exciting articles π
