如何在条件变更OutlinedTextField失焦指示器颜色时避免动画?
解决Jetpack Compose OutlinedTextField失焦指示器颜色切换的动画卡顿问题
你遇到的诡异深色动画卡顿,是因为Compose默认会对OutlinedTextField的指示器颜色变化应用过渡动画,而你在unfocusedIndicatorColor中根据文本内容动态切换颜色时,焦点状态变化和颜色切换的动画叠加导致了异常。以下是两种解决方案:
方案一:禁用颜色过渡动画
通过animateColorAsState配合SnapSpec让颜色切换瞬间完成,无过渡动画:
// 引入依赖:import androidx.compose.animation.core.SnapSpec // 计算目标颜色,使用Snap动画禁用过渡 val unfocusedIndicatorColor by animateColorAsState( targetValue = if (text.isNotEmpty()) { Color(LocalContext.current.color(R.color.black)) } else { Color(LocalContext.current.color(R.color.brand_outline)) }, animationSpec = SnapSpec(), label = "Unfocused Indicator Color" ) // 应用到TextField OutlinedTextField( // 其他参数... colors = OutlinedTextFieldDefaults.colors().copy( focusedIndicatorColor = Color(LocalContext.current.colorAttribute(R.attr.colorTextInputHighlight)), focusedContainerColor = MaterialTheme.colorScheme.surface, unfocusedIndicatorColor = unfocusedIndicatorColor, errorContainerColor = MaterialTheme.colorScheme.surface, errorIndicatorColor = MaterialTheme.colorScheme.error ) )
方案二:自定义指示器完全控制显示
绕过默认的指示器动画,手动绘制指示器:
OutlinedTextField( value = text, onValueChange = { text = it }, // 其他参数... colors = OutlinedTextFieldDefaults.colors().copy( // 隐藏默认指示器 focusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent, focusedContainerColor = MaterialTheme.colorScheme.surface, errorContainerColor = MaterialTheme.colorScheme.surface, errorIndicatorColor = MaterialTheme.colorScheme.error ), // 自定义指示器 indicator = { state -> val indicatorColor = when { state.isFocused -> Color(LocalContext.current.colorAttribute(R.attr.colorTextInputHighlight)) text.isNotEmpty() -> Color(LocalContext.current.color(R.color.black)) else -> Color(LocalContext.current.color(R.color.brand_outline)) } Box( modifier = Modifier .fillMaxWidth() .height(1.dp) .background(indicatorColor) ) } )
两种方案都能解决动画卡顿问题,方案一保留了Compose的颜色状态管理逻辑,方案二更灵活,可自定义指示器样式。
内容的提问来源于stack exchange,提问作者Usama Sarwar
相关产品推荐
相关产品推荐

