如何在Jetpack Compose自定义Composable中实现水平缩放显隐动画?
实现仅X轴的搜索栏显示动画
针对你的需求,这里提供两种可行方案,均仅沿X轴实现搜索栏的显示/隐藏动画,避免Y轴的多余动画:
方案一:自定义缩放动画(仅X轴)
使用AnimatedVisibility并自定义进入/退出动画,强制Y轴缩放保持原始大小,只动画X轴的缩放比例:
// 定义仅X轴的进入/退出动画 val searchEnter = scaleIn( initialScaleX = 0f, initialScaleY = 1f, // Y轴保持原始大小,不参与动画 animationSpec = tween(durationMillis = 300, easing = LinearOutSlowInEasing) ) + fadeIn() val searchExit = scaleOut( targetScaleX = 0f, targetScaleY = 1f, // Y轴保持原始大小,不参与动画 animationSpec = tween(durationMillis = 300, easing = FastOutLinearInEasing) ) + fadeOut() // 替换原AnimatedContent为AnimatedVisibility AnimatedVisibility( visible = isSearchBarVisible, enter = searchEnter, exit = searchExit ) { Row( modifier = Modifier .padding( start = screenWidth * 0.08f, end = 16.dp, top = 8.dp, bottom = 8.dp ), verticalAlignment = Alignment.CenterVertically ) { SearchBar( hint = "Buscar oração", onTextChange = { newText -> searchText = newText }, onSearchClicked = { focusManager.clearFocus() }, onBackClicked = { isSearchBarVisible = false searchText = "" }, focusRequester = focusRequester ) } }
方案二:宽度从0到目标值的动画
通过animateDpAsState控制搜索栏的宽度,从0平滑过渡到目标宽度,实现纯X轴的尺寸展开动画:
// 计算搜索栏的目标宽度(减去左右padding后的可用宽度) val targetWidth = screenWidth - screenWidth * 0.08f - 16.dp // 动画宽度状态 val searchWidth by animateDpAsState( targetValue = if (isSearchBarVisible) targetWidth else 0.dp, animationSpec = tween(durationMillis = 300, easing = LinearOutSlowInEasing) ) // 使用AnimatedContent确保动画过渡流畅 AnimatedContent(targetState = isSearchBarVisible) { visible -> if (visible || searchWidth > 0.dp) { // 确保动画过程中内容可见 Row( modifier = Modifier .padding( start = screenWidth * 0.08f, end = 16.dp, top = 8.dp, bottom = 8.dp ) .width(searchWidth) // 绑定动画宽度 .clip(RoundedCornerShape(16.dp)), // 可选:添加圆角避免宽度变化时的生硬感 verticalAlignment = Alignment.CenterVertically ) { SearchBar( hint = "Buscar oração", onTextChange = { newText -> searchText = newText }, onSearchClicked = { focusManager.clearFocus() }, onBackClicked = { isSearchBarVisible = false searchText = "" }, focusRequester = focusRequester ) } } }
方案选择建议
- 若需要缩放展开/收起的效果,选择方案一;
- 若需要从左到右逐步拉长的尺寸动画,选择方案二。
内容的提问来源于stack exchange,提问作者koiyae
相关产品推荐
相关产品推荐

