Skip to content

Instantly share code, notes, and snippets.

@ryanamaral
Forked from stevdza-san/StopwatchAnimation.kt
Created July 22, 2022 18:01
Show Gist options
  • Save ryanamaral/b3ae3c130fa239b50bc45b3e63958ff3 to your computer and use it in GitHub Desktop.
Save ryanamaral/b3ae3c130fa239b50bc45b3e63958ff3 to your computer and use it in GitHub Desktop.
Create a Stopwatch Animation on a Text with Jetpack Compose
import androidx.compose.animation.*
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewmodel.compose.viewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
@ExperimentalAnimationApi
@Composable
fun MainScreen(mainViewModel: MainViewModel = viewModel()) {
val seconds by mainViewModel.seconds.collectAsState(initial = "00")
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
AnimatedContent(
targetState = seconds,
transitionSpec = {
addAnimation().using(
SizeTransform(clip = false)
)
}
) { targetCount ->
Text(
text = "$targetCount",
style = TextStyle(fontSize = MaterialTheme.typography.h1.fontSize),
textAlign = TextAlign.Center
)
}
}
}
@ExperimentalAnimationApi
fun addAnimation(duration: Int = 800): ContentTransform {
return slideInVertically(animationSpec = tween(durationMillis = duration)) { height -> height } + fadeIn(
animationSpec = tween(durationMillis = duration)
) with slideOutVertically(animationSpec = tween(durationMillis = duration)) { height -> -height } + fadeOut(
animationSpec = tween(durationMillis = duration)
)
}
class MainViewModel : ViewModel() {
val seconds = (0..100)
.asSequence()
.asFlow()
.map {
if (it in 0..9) "0$it" else it
}
.onEach { delay(1000) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment