学习 AnimContent 与 Animatable 使用
package com.gy.composestudy
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.*
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.gy.composestudy.ui.theme.ComposeStudyTheme
import kotlinx.coroutines.delay
import kotlin.math.roundToInt
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeStudyTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
val text = remember {
mutableStateOf("————————————")
}
Column(modifier = Modifier.fillMaxSize()){
Box(modifier = Modifier
.height(100.dp)
.clickable {
text.value = System.currentTimeMillis().toString()
}
.background(Color.Red), contentAlignment = Alignment.Center){
HeadingText("测试文本")
}
Box(modifier = Modifier
.height(100.dp)
.fillMaxWidth()
.background(Color.Red), contentAlignment = Alignment.Center){
NumberChangeAnimatedText(text = text.value)
}
Box(modifier = Modifier
.height(100.dp)
.fillMaxWidth()
.background(Color.Red), contentAlignment = Alignment.Center){
AutoIncreaseAnimatedNumber(number = 10000)
}
}
LaunchedEffect(key1 = Unit, block = {
delay(2000)
text.value = "这是测试动画"
})
}
}
}
}
}
@Composable
fun HeadingText(
text : String,
modifier: Modifier = Modifier,
) {
Text(
modifier = modifier.semantics { heading() },
text = text,
fontSize = 32.sp,
fontWeight = FontWeight.ExtraBold
)
}
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun NumberChangeAnimatedText(
modifier: Modifier = Modifier,
text: String,
textPadding: PaddingValues = PaddingValues(horizontal = 8.dp, vertical = 12.dp),
textSize: TextUnit = 24.sp,
textColor: Color = Color.Black,
textWeight: FontWeight = FontWeight.Normal,
) {
Row(modifier = modifier) {
Log.i("ccccccc","text==$text")
text.forEach {
AnimatedContent(
targetState = it,
transitionSpec = {
slideIntoContainer(AnimatedContentScope.SlideDirection.Up) with
fadeOut() + slideOutOfContainer(AnimatedContentScope.SlideDirection.Up)
}
) { char ->
Text(text = char.toString(), modifier = modifier.padding(textPadding), fontSize = textSize, color = textColor, fontWeight = textWeight)
}
}
}
}
@Composable
fun AutoIncreaseAnimatedNumber(
modifier: Modifier = Modifier,
startAnim: Boolean = true,
number: Int,
durationMills: Int = 16000,
textPadding: PaddingValues = PaddingValues(horizontal = 8.dp, vertical = 12.dp),
textSize: TextUnit = 24.sp,
textColor: Color = Color.Black,
textWeight: FontWeight = FontWeight.Normal
) {
// 动画,Animatable 相关介绍可以见 https://compose.funnysaltyfish.fun/docs/design/animation/animatable?source=trans
val animatedNumber = remember {
androidx.compose.animation.core.Animatable(0f)
}
// 数字格式化后的长度
val l = remember {
number.toString().length
}
// Composable 进入 Composition 阶段,且 startAnim 为 true 时开启动画
LaunchedEffect(number, startAnim) {
if (startAnim)
animatedNumber.animateTo(
targetValue = number.toFloat(),
animationSpec = tween(durationMillis = durationMills)
)
}
NumberChangeAnimatedText(
modifier = modifier,
text = "%0${l}d".format(animatedNumber.value.roundToInt()),
textPadding = textPadding,
textColor = textColor,
textSize = textSize,
textWeight = textWeight
)
}
原文地址: juejin.cn/post/718693…