手动创造AI界面;调整输入框点击区域;创建AI时的三点彩色动画

This commit is contained in:
2025-09-19 18:45:10 +08:00
parent a200d00587
commit cb582393f1
2 changed files with 291 additions and 96 deletions

View File

@@ -29,10 +29,12 @@ import androidx.activity.compose.BackHandler
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@@ -63,6 +65,15 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.ui.draw.shadow import androidx.compose.ui.draw.shadow
import com.aiosman.ravenow.AppState
import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.StartOffset
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.offset
/** /**
* 添加智能体界面 * 添加智能体界面
*/ */
@@ -75,6 +86,7 @@ fun AddAgentScreen() {
var agnetDescError by remember { mutableStateOf<String?>(null) } var agnetDescError by remember { mutableStateOf<String?>(null) }
var errorMessage by remember { mutableStateOf<String?>(null) } var errorMessage by remember { mutableStateOf<String?>(null) }
var isProcessing by remember { mutableStateOf(false) } var isProcessing by remember { mutableStateOf(false) }
var showWaveAnimation by remember { mutableStateOf(false) }
fun onNameChange(value: String) { fun onNameChange(value: String) {
@@ -155,73 +167,95 @@ fun AddAgentScreen() {
} }
} }
Spacer(modifier = Modifier.height(32.dp)) Spacer(modifier = Modifier.height(32.dp))
Column( Column(
modifier = Modifier
.fillMaxWidth()
.height(90.dp)
.padding(horizontal = 20.dp),
) {
Image(
painter = painterResource(id = R.mipmap.group_copy),
contentDescription = "",
modifier = Modifier modifier = Modifier
.fillMaxWidth() .size(48.dp)
.height(113.dp) .clip(
.padding(horizontal = 20.dp), RoundedCornerShape(48.dp)
) { ),
CustomAsyncImage( contentScale = ContentScale.Crop
context, )
model.croppedBitmap, Spacer(modifier = Modifier.height(16.dp))
modifier = Modifier Text(
.size(48.dp) text = "${AppState.profile?.nickName ?: "User"} 你好呀!今天想创造什么?",
.clip( fontSize = 16.sp,
RoundedCornerShape(48.dp) fontWeight = FontWeight.W600
), )
contentDescription = "", }
contentScale = ContentScale.Crop, Spacer(modifier = Modifier.height(8.dp))
placeholderRes = R.mipmap.group_copy var showManualCreation by remember { mutableStateOf(false) }
)
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "Aoisan 你好呀!今天想创造什么?",
fontSize = 16.sp, if (!showManualCreation) {
fontWeight = FontWeight.W600
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "只需要一句话你的专属AI将在这里诞生.",
fontSize = 14.sp
)
}
Spacer(modifier = Modifier.height(24.dp))
Column( Column(
modifier = Modifier modifier = Modifier
.padding(horizontal = 20.dp) .padding(horizontal = 20.dp)
) { ) {
Box { Text(
text = "只需要一句话你的专属AI将在这里诞生。",
fontSize = 14.sp,
color = LocalAppTheme.current.text.copy(alpha = 0.6f),
)
Spacer(modifier = Modifier.height(24.dp))
Box(
modifier = Modifier
.fillMaxWidth()
.height(95.dp)
.shadow(
elevation = 10.dp,
shape = RoundedCornerShape(10.dp),
spotColor = Color(0x33F563FF),
ambientColor = Color(0x99F563FF),
clip = false
)
.background(
brush = Brush.linearGradient(
listOf(
Color(0xFF6246FF),
Color(0xFF7C45ED)
)
),
shape = RoundedCornerShape(10.dp)
)
.padding(0.5.dp)
.background(
color = appColors.inputBackground2,
shape = RoundedCornerShape(10.dp)
)
) {
val focusRequester = remember { FocusRequester() }
val keyboardController = LocalSoftwareKeyboardController.current
Box(
modifier = Modifier
.fillMaxSize()
.noRippleClickable {
model.viewModelScope.launch {
focusRequester.requestFocus()
keyboardController?.show()
}
}
)
FormTextInput2( FormTextInput2(
value = model.desc, value = model.desc,
hint = "一个会写诗的AI一个懂你笑点的AI...", hint = "一个会写诗的AI一个懂你笑点的AI...",
background = appColors.inputBackground2, background = appColors.inputBackground2,
modifier = Modifier.fillMaxWidth().height(95.dp) focusRequester = focusRequester,
// 阴影效果 modifier = Modifier
.shadow( .fillMaxWidth()
elevation = 10.dp, .height(95.dp)
shape = RoundedCornerShape(10.dp),
spotColor = Color(0x33F563FF),
ambientColor = Color(0x99F563FF),
clip = false
)
.background(
brush = Brush.linearGradient(
listOf(
Color(0xFF6246FF),
Color(0xFF7C45ED)
)
),
shape = RoundedCornerShape(10.dp)
)
.padding(0.5.dp)
.background(
color = appColors.inputBackground2,
shape = RoundedCornerShape(10.dp)
)
) { value -> ) { value ->
onDescChange(value) onDescChange(value)
} }
Row( Row(
modifier = Modifier modifier = Modifier
.align(Alignment.BottomEnd) .align(Alignment.BottomEnd)
@@ -231,6 +265,7 @@ fun AddAgentScreen() {
isProcessing = true isProcessing = true
model.viewModelScope.launch { model.viewModelScope.launch {
try { try {
//AI美化功能待实现
} catch (e: Exception) { } catch (e: Exception) {
e.printStackTrace() e.printStackTrace()
} finally { } finally {
@@ -255,44 +290,187 @@ fun AddAgentScreen() {
) )
} }
} }
} }
Spacer(modifier = Modifier.height(24.dp)) Spacer(modifier = Modifier.height(24.dp))
Box( if (showWaveAnimation) {
modifier = Modifier Row(
.align(Alignment.Start) modifier = Modifier
.padding(start = 20.dp) .align(Alignment.Start)
.width(136.dp) .padding(start = 20.dp),
.height(40.dp) verticalAlignment = Alignment.CenterVertically
.border( ) {
width = 1.dp, Box(
color = Color(0x33858B98), modifier = Modifier.size(18.dp)
shape = RoundedCornerShape(12.dp) ) {
) val infiniteTransition = rememberInfiniteTransition()
.background( val dot1Translation by infiniteTransition.animateFloat(
color = appColors.background, initialValue = 0f,
shape = RoundedCornerShape(12.dp), targetValue = -12f,
) animationSpec = infiniteRepeatable(
) { animation = tween(
Row( durationMillis = 1000,
easing = FastOutSlowInEasing
),
repeatMode = RepeatMode.Reverse,
initialStartOffset = StartOffset(0)
)
)
val dot2Translation by infiniteTransition.animateFloat(
initialValue = 0f,
targetValue = -12f,
animationSpec = infiniteRepeatable(
animation = tween(
durationMillis = 1000,
easing = FastOutSlowInEasing
),
repeatMode = RepeatMode.Reverse,
initialStartOffset = StartOffset(333)
)
)
val dot3Translation by infiniteTransition.animateFloat(
initialValue = 0f,
targetValue = -12f,
animationSpec = infiniteRepeatable(
animation = tween(
durationMillis = 1000,
easing = FastOutSlowInEasing
),
repeatMode = RepeatMode.Reverse,
initialStartOffset = StartOffset(666)
)
)
// 三个彩色圆点
Box(
modifier = Modifier
.size(6.dp)
.align(Alignment.BottomStart)
.offset(y = dot1Translation.dp)
.background(Color(0xFFFFD400), CircleShape)
)
Box(
modifier = Modifier
.size(6.dp)
.align(Alignment.BottomCenter)
.offset(y = dot2Translation.dp)
.background(Color(0xFF2F80FF), CircleShape)
)
Box(
modifier = Modifier
.size(6.dp)
.align(Alignment.BottomEnd)
.offset(y = dot3Translation.dp)
.background(Color(0xFF27C84D), CircleShape)
)
}
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "正在为你构思",
color = Color.Black.copy(alpha = 0.6f),
fontSize = 14.sp
)
}
} else {
Box(
modifier = Modifier
.align(Alignment.Start)
.padding(start = 20.dp)
.width(136.dp)
.height(40.dp)
.border(
width = 1.dp,
color = Color(0x33858B98),
shape = RoundedCornerShape(12.dp)
)
.background(
color = appColors.background,
shape = RoundedCornerShape(12.dp),
)
.noRippleClickable {
showManualCreation = true
}
) {
Row(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 18.dp, vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.mipmap.icons_infor_edit),
contentDescription = null,
modifier = Modifier.size(18.dp),
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "手动创造Ai",
color = Color.Black,
fontWeight = FontWeight.W600,
fontSize = 14.sp
)
}
}
}
}else {
// 原版头像的加号
Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .size(72.dp)
.padding(horizontal = 18.dp, vertical = 12.dp), .clip(CircleShape)
verticalAlignment = Alignment.CenterVertically .background(
brush = Brush.linearGradient(
colors = listOf(
Color(0x777c45ed),
Color(0x777c68ef),
Color(0x557bd8f8)
)
)
)
.align(Alignment.Start)
.noRippleClickable {
// 设置正在选择头像的标志
model.isSelectingAvatar = true
navController.navigate(NavigationRoute.AgentImageCrop.route)
},
contentAlignment = Alignment.Center
) { ) {
Icon( Icon(
painter = painterResource(id = R.mipmap.icons_infor_edit), Icons.Default.Add,
contentDescription = null, contentDescription = "Add",
modifier = Modifier.size(18.dp), tint = Color.White,
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = "手动创造Ai",
color = Color.Black,
fontWeight = FontWeight.W600,
fontSize = 14.sp
) )
} }
Spacer(modifier = Modifier.height(18.dp))
// 原版两个输入框
Column(
modifier = Modifier
.padding(horizontal = 16.dp)
) {
FormTextInput(
value = model.name,
label = stringResource(R.string.agent_name),
hint = stringResource(R.string.agent_name_hint),
background = appColors.inputBackground2,
modifier = Modifier.fillMaxWidth(),
) { value ->
onNameChange(value)
}
FormTextInput2(
value = model.desc,
label = stringResource(R.string.agent_desc),
hint = stringResource(R.string.agent_desc_hint),
background = appColors.inputBackground2,
modifier = Modifier.fillMaxWidth(),
) { value ->
onDescChange(value)
}
}
} }
// 错误信息显示 // 错误信息显示
@@ -323,7 +501,7 @@ fun AddAgentScreen() {
) )
), ),
shape = RoundedCornerShape(24.dp) shape = RoundedCornerShape(24.dp)
), ),
color = Color.White, color = Color.White,
backgroundColor = Color.Transparent, backgroundColor = Color.Transparent,
text = stringResource(R.string.create_confirm), text = stringResource(R.string.create_confirm),
@@ -345,6 +523,9 @@ fun AddAgentScreen() {
// 清除之前的错误信息 // 清除之前的错误信息
errorMessage = null errorMessage = null
// 显示波动动画
showWaveAnimation = true
// 调用创建智能体API // 调用创建智能体API
model.viewModelScope.launch { model.viewModelScope.launch {
try { try {
@@ -355,13 +536,16 @@ fun AddAgentScreen() {
navController.popBackStack() navController.popBackStack()
} }
} catch (e: Exception) { } catch (e: Exception) {
// 隐藏波动动画
showWaveAnimation = false
// 显示错误信息 // 显示错误信息
errorMessage = "创建智能体失败: ${e.message}" errorMessage = "创建智能体失败: ${e.message}"
e.printStackTrace() e.printStackTrace()
} }
} }
} }
} }
} }

View File

@@ -23,6 +23,8 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
@@ -44,6 +46,7 @@ fun FormTextInput2(
error: String? = null, error: String? = null,
hint: String? = null, hint: String? = null,
background: Color? = null, background: Color? = null,
focusRequester: FocusRequester? = null,
onValueChange: (String) -> Unit onValueChange: (String) -> Unit
) { ) {
val AppColors = LocalAppTheme.current val AppColors = LocalAppTheme.current
@@ -63,7 +66,7 @@ fun FormTextInput2(
} }
.padding(17.dp), .padding(17.dp),
) { ) {
label?.let { label?.let {
Text( Text(
text = it, text = it,
@@ -97,6 +100,14 @@ fun FormTextInput2(
onValueChange = { onValueChange = {
onValueChange(it) onValueChange(it)
}, },
modifier = Modifier
.let {
if (focusRequester != null) {
it.focusRequester(focusRequester)
} else {
it
}
},
textStyle = TextStyle( textStyle = TextStyle(
fontSize = 16.sp, fontSize = 16.sp,
fontWeight = FontWeight.Normal, fontWeight = FontWeight.Normal,