我的-编辑-ui调整
This commit is contained in:
@@ -4,19 +4,26 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.ArrowForward
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.Edit as EditIcon
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -28,10 +35,14 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.aiosman.ravenow.AppState
|
||||
import com.aiosman.ravenow.AppStore
|
||||
@@ -39,26 +50,26 @@ import com.aiosman.ravenow.LocalAppTheme
|
||||
import com.aiosman.ravenow.LocalNavController
|
||||
import com.aiosman.ravenow.R
|
||||
import com.aiosman.ravenow.ui.NavigationRoute
|
||||
import com.aiosman.ravenow.ui.comment.NoticeScreenHeader
|
||||
import com.aiosman.ravenow.ui.composables.CustomAsyncImage
|
||||
import com.aiosman.ravenow.ui.composables.StatusBarMaskLayout
|
||||
import com.aiosman.ravenow.ui.composables.StatusBarSpacer
|
||||
import com.aiosman.ravenow.ui.composables.form.FormTextInput
|
||||
import com.aiosman.ravenow.ui.composables.debouncedClickable
|
||||
import com.aiosman.ravenow.ui.composables.rememberDebouncedNavigation
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.systemBars
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import com.aiosman.ravenow.ConstVars
|
||||
import com.aiosman.ravenow.ui.composables.pickupAndCompressLauncher
|
||||
import java.io.File
|
||||
@@ -134,192 +145,28 @@ fun AccountEditScreen2(onUpdateBanner: ((Uri, File, Context) -> Unit)? = null,)
|
||||
// 确保显示的是当前登录用户的信息,而不是之前用户的缓存数据
|
||||
model.reloadProfile()
|
||||
}
|
||||
|
||||
// 设置状态栏为透明,使用浅色图标(因为顶部背景是深色图片)
|
||||
val systemUiController = rememberSystemUiController()
|
||||
LaunchedEffect(Unit) {
|
||||
systemUiController.setStatusBarColor(Color.Transparent, darkIcons = false)
|
||||
}
|
||||
|
||||
StatusBarMaskLayout(
|
||||
modifier = Modifier.background(color = appColors.background).padding(horizontal = 16.dp),
|
||||
darkIcons = !AppState.darkMode,
|
||||
maskBoxBackgroundColor = appColors.background
|
||||
modifier = Modifier.background(Color(0xFFFAF9FB)),
|
||||
darkIcons = false, // 浅色图标(白色),因为顶部背景是深色
|
||||
maskBoxBackgroundColor = Color.Transparent
|
||||
) {
|
||||
Column(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(color = appColors.background),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
.background(Color(0xFFFAF9FB))
|
||||
) {
|
||||
//StatusBarSpacer()
|
||||
Box(
|
||||
modifier = Modifier.padding(horizontal = 0.dp, vertical = 16.dp)
|
||||
) {
|
||||
NoticeScreenHeader(
|
||||
title = stringResource(R.string.edit_profile),
|
||||
moreIcon = false
|
||||
) {
|
||||
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.size(24.dp)
|
||||
.debouncedClickable(
|
||||
enabled = validate() && !model.isUpdating,
|
||||
debounceTime = 1000L
|
||||
) {
|
||||
if (validate() && !model.isUpdating) {
|
||||
model.viewModelScope.launch {
|
||||
model.isUpdating = true
|
||||
model.updateUserProfile(context)
|
||||
model.viewModelScope.launch(Dispatchers.Main) {
|
||||
debouncedNavigation {
|
||||
navController.navigateUp()
|
||||
}
|
||||
model.isUpdating = false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
imageVector = Icons.Default.Check,
|
||||
contentDescription = "保存",
|
||||
tint = if (validate() && !model.isUpdating) appColors.text else appColors.nonActiveText
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 添加横幅图片区域
|
||||
val banner = model.profile?.banner
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(300.dp)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
) {
|
||||
if (banner != null) {
|
||||
CustomAsyncImage(
|
||||
context = LocalContext.current,
|
||||
imageUrl = banner,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentDescription = "Banner",
|
||||
contentScale = ContentScale.Crop
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color.Gray.copy(alpha = 0.1f))
|
||||
)
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(120.dp)
|
||||
.height(42.dp)
|
||||
.align(Alignment.BottomEnd)
|
||||
.padding(end = 12.dp, bottom = 12.dp)
|
||||
.background(
|
||||
color = Color.Black.copy(alpha = 0.4f),
|
||||
shape = RoundedCornerShape(9.dp)
|
||||
)
|
||||
.noRippleClickable {
|
||||
Intent(Intent.ACTION_PICK).apply {
|
||||
type = "image/*"
|
||||
pickBannerImageLauncher.launch(this)
|
||||
}
|
||||
}
|
||||
){
|
||||
Text(
|
||||
text = "change",
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.W600,
|
||||
color = Color.White,
|
||||
modifier = Modifier.align(Alignment.Center)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
||||
// 显示内容或加载状态
|
||||
Log.d("AccountEditScreen2", "UI状态 - profile: ${model.profile?.nickName}, isLoading: ${model.isLoading}")
|
||||
when {
|
||||
model.profile != null -> {
|
||||
Log.d("AccountEditScreen2", "显示用户资料内容")
|
||||
// 有数据时显示内容
|
||||
val it = model.profile!!
|
||||
Box(
|
||||
modifier = Modifier.size(88.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
CustomAsyncImage(
|
||||
context,
|
||||
model.croppedBitmap ?: it.avatar,
|
||||
modifier = Modifier
|
||||
.size(88.dp)
|
||||
.clip(
|
||||
RoundedCornerShape(88.dp)
|
||||
),
|
||||
contentDescription = "",
|
||||
contentScale = ContentScale.Crop
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(32.dp)
|
||||
.clip(CircleShape)
|
||||
.background(
|
||||
brush = Brush.linearGradient(
|
||||
colors = listOf(
|
||||
Color(0xFF7c45ed),
|
||||
Color(0x997c68ef),
|
||||
Color(0xFF7bd8f8)
|
||||
)
|
||||
),
|
||||
)
|
||||
.align(Alignment.BottomEnd)
|
||||
.debouncedClickable(
|
||||
debounceTime = 800L
|
||||
) {
|
||||
debouncedNavigation {
|
||||
navController.navigate(NavigationRoute.ImageCrop.route)
|
||||
}
|
||||
},
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Add,
|
||||
contentDescription = "Add",
|
||||
tint = Color.White,
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(18.dp))
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(horizontal = 16.dp)
|
||||
) {
|
||||
FormTextInput(
|
||||
value = model.name,
|
||||
label = stringResource(R.string.nickname),
|
||||
hint = "Input nickname",
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
error = usernameError
|
||||
) { value ->
|
||||
onNicknameChange(value)
|
||||
}
|
||||
FormTextInput(
|
||||
value = model.bio,
|
||||
label = stringResource(R.string.bio),
|
||||
hint = "Input bio",
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
error = bioError
|
||||
) { value ->
|
||||
onBioChange(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
model.isLoading -> {
|
||||
Log.d("AccountEditScreen2", "显示加载指示器")
|
||||
// 加载中状态
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
androidx.compose.material3.CircularProgressIndicator(
|
||||
@@ -327,24 +174,460 @@ fun AccountEditScreen2(onUpdateBanner: ((Uri, File, Context) -> Unit)? = null,)
|
||||
)
|
||||
}
|
||||
}
|
||||
model.profile != null -> {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
// 顶部背景区域(圆角在底部,覆盖状态栏)
|
||||
val banner = model.profile?.banner
|
||||
val statusBarPadding = WindowInsets.systemBars.asPaddingValues().calculateTopPadding()
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.offset(y = -statusBarPadding)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(402.dp)
|
||||
.height(206.dp)
|
||||
.align(Alignment.TopCenter)
|
||||
.clip(RoundedCornerShape(bottomStart = 32.dp, bottomEnd = 32.dp))
|
||||
) {
|
||||
if (banner != null) {
|
||||
CustomAsyncImage(
|
||||
context = context,
|
||||
imageUrl = banner,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentDescription = "Banner",
|
||||
contentScale = ContentScale.Crop
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color.Gray.copy(alpha = 0.2f))
|
||||
)
|
||||
}
|
||||
|
||||
// 更换封面按钮(位于壁纸右下方)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomEnd)
|
||||
.padding(end = 16.dp, bottom = 20.dp)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.background(Color(0x5C7D7C80)) // RGB(125, 120, 128, 0.36)
|
||||
.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||
.noRippleClickable {
|
||||
Intent(Intent.ACTION_PICK).apply {
|
||||
type = "image/*"
|
||||
pickBannerImageLauncher.launch(this)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
// 更换封面图标
|
||||
Icon(
|
||||
painter = painterResource(
|
||||
id = if (AppState.darkMode) {
|
||||
// TODO: 添加更换封面暗色模式图标
|
||||
R.mipmap.frame_4 // 临时占位,需替换为实际图标
|
||||
} else {
|
||||
// TODO: 添加更换封面亮色模式图标
|
||||
R.mipmap.fengm // 临时占位,需替换为实际图标
|
||||
}
|
||||
),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(16.dp),
|
||||
tint = Color.White
|
||||
)
|
||||
Text(
|
||||
text = "更换封面",
|
||||
fontSize = 12.sp,
|
||||
color = Color.White
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 状态栏区域(时间、信号、电池)
|
||||
// 这里使用系统状态栏,不单独实现
|
||||
|
||||
// 导航栏区域
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp)
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(statusBarPadding + 12.dp))
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 12.dp)
|
||||
) {
|
||||
// 返回按钮
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(44.dp)
|
||||
.clip(CircleShape)
|
||||
.background(Color.White.copy(alpha = 0.3f))
|
||||
.noRippleClickable {
|
||||
navController.navigateUp()
|
||||
}
|
||||
.align(Alignment.CenterStart),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Image(
|
||||
painter = painterResource(id = R.drawable.rider_pro_back_icon),
|
||||
contentDescription = "Back",
|
||||
modifier = Modifier.size(24.dp),
|
||||
colorFilter = ColorFilter.tint(Color.White)
|
||||
)
|
||||
}
|
||||
|
||||
// 标题
|
||||
Text(
|
||||
text = "编辑资料",
|
||||
fontSize = 17.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
color = Color.White,
|
||||
modifier = Modifier.align(Alignment.Center)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 用户头像区域(距离顶部-50dp,包含状态栏高度,左右居中)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.offset(y = (-50).dp - statusBarPadding),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
val it = model.profile!!
|
||||
Box(
|
||||
modifier = Modifier.size(96.dp),
|
||||
contentAlignment = Alignment.BottomEnd
|
||||
) {
|
||||
// 头像
|
||||
CustomAsyncImage(
|
||||
context,
|
||||
model.croppedBitmap ?: it.avatar,
|
||||
modifier = Modifier
|
||||
.size(96.dp)
|
||||
.clip(CircleShape)
|
||||
.border(2.4.dp, Color(0xFFFAF9FB), CircleShape),
|
||||
contentDescription = "",
|
||||
contentScale = ContentScale.Crop
|
||||
)
|
||||
|
||||
// 编辑头像按钮
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(28.dp)
|
||||
.clip(CircleShape)
|
||||
.background(Color(0xFF110C13))
|
||||
.border(2.dp, Color.White, CircleShape)
|
||||
.debouncedClickable(debounceTime = 800L) {
|
||||
debouncedNavigation {
|
||||
navController.navigate(NavigationRoute.ImageCrop.route)
|
||||
}
|
||||
},
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(
|
||||
id = if (AppState.darkMode) {
|
||||
// TODO: 添加编辑头像暗色模式图标
|
||||
R.mipmap.frame_4 // 临时占位,需替换为实际图标
|
||||
} else {
|
||||
// TODO: 添加编辑头像亮色模式图标
|
||||
R.mipmap.bi // 临时占位,需替换为实际图标
|
||||
}
|
||||
),
|
||||
contentDescription = "Edit Avatar",
|
||||
modifier = Modifier.size(16.dp),
|
||||
tint = Color.White
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f)
|
||||
.padding(horizontal = 16.dp)
|
||||
.offset(y = (-74).dp)//
|
||||
) {
|
||||
// 昵称输入框
|
||||
ProfileInfoCard(
|
||||
label = "昵称",
|
||||
value = model.name,
|
||||
placeholder = "Value",
|
||||
onValueChange = { onNicknameChange(it) },
|
||||
isMultiline = false
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// 个人简介输入框
|
||||
ProfileInfoCard(
|
||||
label = "个人简介",
|
||||
value = model.bio,
|
||||
placeholder = "Welcome to my fantiac word i will show you something about magic",
|
||||
onValueChange = { onBioChange(it) },
|
||||
isMultiline = true
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// MBTI 类型和星座
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(Color.White)
|
||||
) {
|
||||
// MBTI 类型
|
||||
ProfileSelectItem(
|
||||
label = "MBTI 类型",
|
||||
value = model.mbti ?: "ENFP",
|
||||
iconColor = Color(0xFF7C45ED),
|
||||
iconResDark = null, // TODO: 添加MBTI暗色模式图标
|
||||
iconResLight = null, // TODO: 添加MBTI亮色模式图标
|
||||
onClick = {
|
||||
debouncedNavigation {
|
||||
navController.navigate(NavigationRoute.MbtiSelect.route)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// 分隔线
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(0.3.dp)
|
||||
.background(Color(0x41413C43).copy(alpha = 0.2f))
|
||||
.padding(horizontal = 16.dp)
|
||||
)
|
||||
|
||||
// 星座(使用当前图标)
|
||||
ProfileSelectItem(
|
||||
label = "星座",
|
||||
value = model.zodiac ?: "白羊座",
|
||||
iconColor = Color(0xFFFFCC00),
|
||||
iconResDark = R.mipmap.frame_4, // 星座暗色模式图标
|
||||
iconResLight = R.mipmap.xingzuo, // 星座亮色模式图标
|
||||
onClick = {
|
||||
debouncedNavigation {
|
||||
navController.navigate(NavigationRoute.ZodiacSelect.route)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
// 保存按钮
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(50.dp)
|
||||
.clip(RoundedCornerShape(1000.dp))
|
||||
.background(
|
||||
brush = Brush.horizontalGradient(
|
||||
colors = listOf(
|
||||
Color(0xFF7C45ED), // RGB(124, 69, 237) - 左侧
|
||||
Color(0xFF7C57EE), // RGB(124, 87, 238) - 中间
|
||||
Color(0xFF7BD8F8) // RGB(123, 216, 248) - 右侧
|
||||
)
|
||||
)
|
||||
)
|
||||
.debouncedClickable(
|
||||
enabled = validate() && !model.isUpdating,
|
||||
debounceTime = 1000L
|
||||
) {
|
||||
if (validate() && !model.isUpdating) {
|
||||
model.viewModelScope.launch {
|
||||
model.isUpdating = true
|
||||
model.updateUserProfile(context)
|
||||
model.viewModelScope.launch(Dispatchers.Main) {
|
||||
debouncedNavigation {
|
||||
navController.navigateUp()
|
||||
}
|
||||
model.isUpdating = false
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = "保存",
|
||||
fontSize = 17.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color.White
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
Log.d("AccountEditScreen2", "显示错误信息 - 没有数据且不在加载中")
|
||||
// 没有数据且不在加载中,显示错误信息
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
androidx.compose.material3.Text(
|
||||
Text(
|
||||
text = "加载用户资料失败,请重试",
|
||||
color = appColors.text
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 信息输入卡片组件
|
||||
*/
|
||||
@Composable
|
||||
fun ProfileInfoCard(
|
||||
label: String,
|
||||
value: String,
|
||||
placeholder: String,
|
||||
onValueChange: (String) -> Unit,
|
||||
isMultiline: Boolean = false
|
||||
) {
|
||||
val appColors = LocalAppTheme.current
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(if (isMultiline) 66.dp else 56.dp) // 昵称框高度56dp,个人简介66dp
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(Color.White),
|
||||
contentAlignment = if (isMultiline) Alignment.TopStart else Alignment.CenterStart
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp)
|
||||
.padding(vertical = if (isMultiline) 11.dp else 0.dp),
|
||||
verticalAlignment = if (isMultiline) Alignment.Top else Alignment.CenterVertically
|
||||
) {
|
||||
// 标签
|
||||
Text(
|
||||
text = label,
|
||||
fontSize = 17.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color.Black,
|
||||
modifier = Modifier.width(100.dp)
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
|
||||
// 输入框
|
||||
Box(
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
if (value.isEmpty()) {
|
||||
Text(
|
||||
text = placeholder,
|
||||
fontSize = if (isMultiline) 15.sp else 17.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color(0x993C3C43),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
|
||||
BasicTextField(
|
||||
value = value,
|
||||
onValueChange = onValueChange,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
textStyle = androidx.compose.ui.text.TextStyle(
|
||||
fontSize = if (isMultiline) 15.sp else 17.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color.Black
|
||||
),
|
||||
cursorBrush = SolidColor(Color.Black),
|
||||
maxLines = if (isMultiline) Int.MAX_VALUE else 1,
|
||||
singleLine = !isMultiline
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择项组件(MBTI、星座)
|
||||
*/
|
||||
@Composable
|
||||
fun ProfileSelectItem(
|
||||
label: String,
|
||||
value: String,
|
||||
iconColor: Color,
|
||||
onClick: () -> Unit,
|
||||
iconResDark: Int? = null,
|
||||
iconResLight: Int? = null
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(56.dp)
|
||||
.clickable(onClick = onClick)
|
||||
.padding(horizontal = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
// 自定义图标
|
||||
Icon(
|
||||
painter = painterResource(
|
||||
id = if (AppState.darkMode) {
|
||||
iconResDark ?: R.mipmap.frame_4 // 使用传入的暗色模式图标,或默认占位
|
||||
} else {
|
||||
iconResLight ?: R.mipmap.naoz // 使用传入的亮色模式图标,或默认占位
|
||||
}
|
||||
),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(24.dp),
|
||||
tint = iconColor
|
||||
)
|
||||
|
||||
Text(
|
||||
text = label,
|
||||
fontSize = 17.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color.Black
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = value,
|
||||
fontSize = 17.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color(0x993C3C43)
|
||||
)
|
||||
|
||||
Icon(
|
||||
imageVector = Icons.Default.ArrowForward,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(8.dp),
|
||||
tint = Color(0x4D3C3C43)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user