如何在 Jetpack Compose 中为字符串设置动画?

时间:2021-06-15 12:07:58

标签: android animation android-jetpack-compose

我有一个字符串“(+91)”。我如何设置动画,以便在某些动作中,“(+91)”逐渐淡入,而在其他某些动作中,“(+91)” 逐渐淡出。在visualTransformation的帮助下,我在文本字段中使用“(+91)”作为前缀。

这是我用于文本字段的代码:

    TextField(
        value = query3.value,
        onValueChange = { newValue ->
            query3.value = newValue
            mobErrorVisible.value = false
        },

   visualTransformation = if (showCode){
                    PrefixTransformation("(+91)")} //Animate (+91)
            else
                    PrefixTransformation(""), 
        
            label = {
            Text(
                "Mobile Number",
                color = colorResource(id = R.color.bright_green),
                fontFamily = FontFamily(Font(R.font.poppins_regular)),
                fontSize = with(LocalDensity.current) { dimensionResource(id = R.dimen._12ssp).toSp() })
                
        },
        interactionSource = interactionSource,
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
        textStyle = TextStyle(
            textAlign = TextAlign.Start,
            color = colorResource(id = R.color.bright_green),
            fontFamily = FontFamily(Font(R.font.poppins_regular)),
            fontSize = with(LocalDensity.current) { dimensionResource(id = R.dimen._16ssp).toSp() }
        ),
        modifier = Modifier
            .drawBehind {
                val strokeWidth = indicatorWidth.value * density
                val y = size.height - strokeWidth / 2
                drawLine(
                    indicatorColor,
                    Offset(TextFieldPadding.toPx(), y),
                    Offset(size.width - TextFieldPadding.toPx(), y),
                    strokeWidth
                )
            }
            .focusRequester(focusRequester)
            .onFocusChanged { showCode = (it.isFocused || query3.value != "")}
            .constrainAs(phone) {
                top.linkTo(glPhone)
                bottom.linkTo(glPhoneBottom)
                start.linkTo(glLeft)
                end.linkTo(glRight)
                width = Dimension.fillToConstraints
                height = Dimension.fillToConstraints
            },
        colors = TextFieldDefaults.textFieldColors(
            backgroundColor = Color.Transparent,
            focusedIndicatorColor = Transparent,
            unfocusedIndicatorColor = Transparent,
            disabledIndicatorColor = Transparent
        )
    )

这是我的 PrefixTransformation 类:

 class PrefixTransformation(val prefix: String) : VisualTransformation {
    override fun filter(text: AnnotatedString): TransformedText {
        return PrefixFilter(text, prefix)
    }
}

这是我的 PrefixFilter() 函数:

fun PrefixFilter(number: AnnotatedString, prefix: String): TransformedText {

    var out = prefix + " " + number.text
    val prefixOffset = prefix.length

    val numberOffsetTranslator = object : OffsetMapping {
        override fun originalToTransformed(offset: Int): Int {
            return offset + prefixOffset
        }

        override fun transformedToOriginal(offset: Int): Int {
            if (offset <= prefixOffset-1) return prefixOffset
            return offset - prefixOffset
        }
    }

    return TransformedText(AnnotatedString(out), numberOffsetTranslator)
}

我们可以将颜色设置为:

val color = remember { Animatable(Color.Gray) }
LaunchedEffect(ok) {
    color.animateTo(if (ok) Color.Green else Color.Red)
}
Box(Modifier.fillMaxSize().background(color.value))

但是我们如何为字符串设置动画?

2 个答案:

答案 0 :(得分:0)

您需要的是 animatedVisibility 可组合。 这是一个示例,其中文本的可见性由按钮控制

Box(
    modifier = Modifier
        .fillMaxSize()
) {
    var visible by remember { mutableStateOf(false) }

    Button(
        modifier = Modifier.align(Alignment.TopCenter),
        onClick = {
            visible = !visible
        }
    ) {
        Text("Toggle Visibility")
    }

    val animationDuration = 2000

    AnimatedVisibility(
        modifier = Modifier.align(Alignment.BottomCenter),
        visible = visible,
        enter = fadeIn(animationSpec = tween(durationMillis = animationDuration)),
        exit = fadeOut(animationSpec = tween(durationMillis = animationDuration))
    ) {
        Text("ABC")
    }
}

答案 1 :(得分:0)

明智的解决方案是为国家/地区代码使用单独的 Composable。这样您就可以将 Composable 包装在 crossfade 或仅 AnimatedVisibility 之类的东西中(从 compose 1.0.0-beta07 开始是实验性的)