Skip to content

Instantly share code, notes, and snippets.

@stevdza-san
Created June 29, 2022 18:54
Show Gist options
  • Save stevdza-san/443aa8fd01445902c3935beff4be92c5 to your computer and use it in GitHub Desktop.
Save stevdza-san/443aa8fd01445902c3935beff4be92c5 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