Merge pull request #16 from Zhong202501/main

粉丝 关注 评论UI调整
This commit is contained in:
Weber
2025-08-25 10:09:57 +08:00
committed by GitHub
7 changed files with 417 additions and 368 deletions

View File

@@ -76,6 +76,7 @@ fun NoticeScreenHeader(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
) {
//返回tab
Image(
painter = painterResource(id = R.drawable.rider_pro_back_icon,),
contentDescription = title,
@@ -88,6 +89,7 @@ fun NoticeScreenHeader(
colorFilter = ColorFilter.tint(AppColors.text)
)
Spacer(modifier = Modifier.size(12.dp))
Spacer(modifier = Modifier.width(110.dp))
Text(title, fontWeight = FontWeight.W800, fontSize = 17.sp, color = AppColors.text)
if (moreIcon) {
Spacer(modifier = Modifier.weight(1f))

View File

@@ -22,7 +22,9 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
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.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@@ -75,73 +77,105 @@ fun CommentNoticeScreen() {
) {
NoticeScreenHeader(stringResource(R.string.comment), moreIcon = false)
}
LazyColumn(
modifier = Modifier
.fillMaxSize().padding(horizontal = 16.dp)
) {
items(comments.itemCount) { index ->
comments[index]?.let { comment ->
CommentNoticeItem(comment) {
viewModel.updateReadStatus(comment.id)
viewModel.viewModelScope.launch {
var highlightCommentId = comment.id
comment.parentCommentId?.let {
highlightCommentId = it
if (comments.itemCount == 0 && comments.loadState.refresh is LoadState.NotLoading) {
Box(
modifier = Modifier
.fillMaxSize()
.padding(top = 188.dp),
contentAlignment = Alignment.TopCenter
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxWidth()
) {
androidx.compose.foundation.Image(
painter = painterResource(id = R.mipmap.rider_pro_followers_empty),
contentDescription = null,
modifier = Modifier.size(140.dp)
)
Spacer(modifier = Modifier.size(24.dp))
Text(
text = "Wait for the first traveler to appear~",
color = AppColors.text,
fontSize = 16.sp,
fontWeight = FontWeight.W600
)
Spacer(modifier = Modifier.size(8.dp))
Text(
text = "Post to connect.",
color = AppColors.text,
fontSize = 16.sp,
fontWeight = FontWeight.W400
)
}
}
} else {
LazyColumn(
modifier = Modifier
.fillMaxSize().padding(horizontal = 16.dp)
) {
items(comments.itemCount) { index ->
comments[index]?.let { comment ->
CommentNoticeItem(comment) {
viewModel.updateReadStatus(comment.id)
viewModel.viewModelScope.launch {
var highlightCommentId = comment.id
comment.parentCommentId?.let {
highlightCommentId = it
}
navController.navigateToPost(
id = comment.post!!.id,
highlightCommentId = highlightCommentId,
initImagePagerIndex = 0
)
}
navController.navigateToPost(
id = comment.post!!.id,
highlightCommentId = highlightCommentId,
initImagePagerIndex = 0
)
}
}
}
}
// handle load error
when {
comments.loadState.append is LoadState.Loading -> {
item {
Box(
modifier = Modifier
.fillMaxWidth()
.height(64.dp)
.padding(16.dp),
contentAlignment = Alignment.Center
) {
LinearProgressIndicator(
modifier = Modifier.width(160.dp),
color = AppColors.main
)
// handle load error
when {
comments.loadState.append is LoadState.Loading -> {
item {
Box(
modifier = Modifier
.fillMaxWidth()
.height(64.dp)
.padding(16.dp),
contentAlignment = Alignment.Center
) {
LinearProgressIndicator(
modifier = Modifier.width(160.dp),
color = AppColors.main
)
}
}
}
}
comments.loadState.append is LoadState.Error -> {
item {
Box(
modifier = Modifier
.fillMaxWidth()
.height(64.dp)
.noRippleClickable {
comments.retry()
},
contentAlignment = Alignment.Center
) {
Text(
text = "Load comment error, click to retry",
color = AppColors.text
)
comments.loadState.append is LoadState.Error -> {
item {
Box(
modifier = Modifier
.fillMaxWidth()
.height(64.dp)
.noRippleClickable {
comments.retry()
},
contentAlignment = Alignment.Center
) {
Text(
text = "Load comment error, click to retry",
color = AppColors.text
)
}
}
}
}
}
item {
Spacer(modifier = Modifier.height(72.dp))
item {
Spacer(modifier = Modifier.height(72.dp))
}
}
}
}
}
@Composable

View File

@@ -1,10 +1,14 @@
package com.aiosman.ravenow.ui.follower
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.pullrefresh.PullRefreshIndicator
@@ -15,8 +19,11 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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.viewmodel.compose.viewModel
import androidx.paging.compose.collectAsLazyPagingItems
import com.aiosman.ravenow.AppState
@@ -55,39 +62,73 @@ fun FollowerListScreen(userId: Int) {
) {
NoticeScreenHeader(stringResource(R.string.followers_upper), moreIcon = false)
}
Box(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.pullRefresh(refreshState)
) {
LazyColumn(
modifier = Modifier.fillMaxSize()
if (users.itemCount == 0) {
Box(
modifier = Modifier
.fillMaxSize()
.padding(top = 188.dp),
contentAlignment = Alignment.TopCenter
) {
items(users.itemCount) { index ->
users[index]?.let { user ->
FollowItem(
avatar = user.avatar,
nickname = user.nickName,
userId = user.id,
isFollowing = user.isFollowing
) {
scope.launch {
if (user.isFollowing) {
model.unFollowUser(user.id)
} else {
model.followUser(user.id)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxWidth()
) {
Image(
painter = painterResource(id = R.mipmap.rider_pro_followers_empty),
contentDescription = null,
modifier = Modifier.size(140.dp)
)
Spacer(modifier = Modifier.size(24.dp))
androidx.compose.material.Text(
text = "No one's paying attention to you yet",
color = appColors.text,
fontSize = 16.sp,
fontWeight = FontWeight.W600
)
Spacer(modifier = Modifier.size(8.dp))
androidx.compose.material.Text(
text = "Your vibe attracts your tribe.",
color = appColors.text,
fontSize = 16.sp,
fontWeight = FontWeight.W400
)
}
}
} else {
Box(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.pullRefresh(refreshState)
) {
LazyColumn(
modifier = Modifier.fillMaxSize()
) {
items(users.itemCount) { index ->
users[index]?.let { user ->
FollowItem(
avatar = user.avatar,
nickname = user.nickName,
userId = user.id,
isFollowing = user.isFollowing
) {
scope.launch {
if (user.isFollowing) {
model.unFollowUser(user.id)
} else {
model.followUser(user.id)
}
}
}
}
}
}
PullRefreshIndicator(
refreshing = model.isLoading,
state = refreshState,
modifier = Modifier.align(Alignment.TopCenter)
)
}
PullRefreshIndicator(
refreshing = model.isLoading,
state = refreshState,
modifier = Modifier.align(Alignment.TopCenter)
)
}
}
}

View File

@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Column
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.lazy.LazyColumn
@@ -61,12 +62,14 @@ fun FollowingListScreen(userId: Int) {
.padding(vertical = 16.dp)
) {
NoticeScreenHeader(stringResource(R.string.following_upper), moreIcon = false)
}
if(users.itemCount == 0) {
Box(
modifier = Modifier
.fillMaxSize(),
contentAlignment = Alignment.Center
.fillMaxSize()
.padding(top=188.dp),
contentAlignment = Alignment.TopCenter
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
@@ -77,14 +80,14 @@ fun FollowingListScreen(userId: Int) {
contentDescription = null,
modifier = Modifier.size(140.dp)
)
Spacer(modifier = Modifier.size(32.dp))
Spacer(modifier = Modifier.size(24.dp))
androidx.compose.material.Text(
text = "You haven't followed anyone yet",
color = appColors.text,
fontSize = 16.sp,
fontWeight = FontWeight.W600
)
Spacer(modifier = Modifier.size(16.dp))
Spacer(modifier = Modifier.size(8.dp))
androidx.compose.material.Text(
text = "Click start your social journey.",
color = appColors.text,
@@ -129,6 +132,5 @@ fun FollowingListScreen(userId: Int) {
)
}
}
}
}

View File

@@ -79,7 +79,7 @@ fun MomentsList() {
// center the tabs
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically
) {
) {//探索tab
Column(
modifier = Modifier
.noRippleClickable {
@@ -108,38 +108,8 @@ fun MomentsList() {
.width(34.dp)
.height(4.dp)
)
}
Spacer(modifier = Modifier.width(16.dp))
Column(
modifier = Modifier
.noRippleClickable {
scope.launch {
pagerState.animateScrollToPage(1)
}
},
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = stringResource(R.string.index_dynamic),
fontSize = 16.sp,
color = if (pagerState.currentPage == 1) AppColors.text else AppColors.nonActiveText,
fontWeight = FontWeight.W600)
Spacer(modifier = Modifier.height(4.dp))
Image(
painter = painterResource(
if (pagerState.currentPage == 1) R.mipmap.tab_indicator_selected
else R.drawable.tab_indicator_unselected
),
contentDescription = "tab indicator",
modifier = Modifier
.width(34.dp)
.height(4.dp)
)
}
//“关注”tab
Spacer(modifier = Modifier.width(16.dp))
Column(
modifier = Modifier

View File

@@ -147,89 +147,89 @@ fun Explore() {
fun AgentCard2(agentItem: AgentItem) {
val AppColors = LocalAppTheme.current
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically
) {
// 左侧头像
Box(
Row(
modifier = Modifier
.size(48.dp)
.background(Color(0xFFF5F5F5), RoundedCornerShape(24.dp)),
contentAlignment = Alignment.Center
.fillMaxWidth()
.padding(vertical = 12.dp),
verticalAlignment = Alignment.CenterVertically
) {
if (agentItem.avatar.isNotEmpty()) {
CustomAsyncImage(
imageUrl = agentItem.avatar,
contentDescription = "Agent头像",
modifier = Modifier
.size(48.dp)
.clip(RoundedCornerShape(24.dp)),
contentScale = androidx.compose.ui.layout.ContentScale.Crop
// 左侧头像
Box(
modifier = Modifier
.size(48.dp)
.background(Color(0xFFF5F5F5), RoundedCornerShape(24.dp)),
contentAlignment = Alignment.Center
) {
if (agentItem.avatar.isNotEmpty()) {
CustomAsyncImage(
imageUrl = agentItem.avatar,
contentDescription = "Agent头像",
modifier = Modifier
.size(48.dp)
.clip(RoundedCornerShape(24.dp)),
contentScale = androidx.compose.ui.layout.ContentScale.Crop
)
} else {
Image(
painter = painterResource(R.mipmap.rider_pro_agent),
contentDescription = "默认头像",
modifier = Modifier.size(24.dp),
colorFilter = ColorFilter.tint(AppColors.secondaryText)
)
}
}
Spacer(modifier = Modifier.width(12.dp))
// 中间文字内容
Column(
modifier = Modifier
.weight(1f)
.padding(end = 8.dp)
) {
// 标题
Text(
text = agentItem.title,
fontSize = 14.sp,
fontWeight = androidx.compose.ui.text.font.FontWeight.W600,
color = AppColors.text,
maxLines = 1,
overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis
)
} else {
Image(
painter = painterResource(R.mipmap.rider_pro_agent),
contentDescription = "默认头像",
modifier = Modifier.size(24.dp),
colorFilter = ColorFilter.tint(AppColors.secondaryText)
Spacer(modifier = Modifier.height(8.dp))
// 描述
Text(
text = agentItem.desc,
fontSize = 12.sp,
color = AppColors.secondaryText,
maxLines = 1,
overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis
)
}
// 右侧聊天按钮
Box(
modifier = Modifier
.size(width = 60.dp, height = 32.dp)
.background(
color = Color(0X147c7480),
shape = RoundedCornerShape(8.dp)
)
.clickable {
// 聊天逻辑
},
contentAlignment = Alignment.Center
) {
Text(
text = "聊天",
fontSize = 12.sp,
color = AppColors.text,
fontWeight = androidx.compose.ui.text.font.FontWeight.W500
)
}
}
Spacer(modifier = Modifier.width(12.dp))
// 中间文字内容
Column(
modifier = Modifier
.weight(1f)
.padding(end = 8.dp)
) {
// 标题
Text(
text = agentItem.title,
fontSize = 14.sp,
fontWeight = androidx.compose.ui.text.font.FontWeight.W600,
color = AppColors.text,
maxLines = 1,
overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis
)
Spacer(modifier = Modifier.height(8.dp))
// 描述
Text(
text = agentItem.desc,
fontSize = 12.sp,
color = AppColors.secondaryText,
maxLines = 1,
overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis
)
}
// 右侧聊天按钮
Box(
modifier = Modifier
.size(width = 60.dp, height = 32.dp)
.background(
color = Color(0X147c7480),
shape = RoundedCornerShape(8.dp)
)
.clickable {
// 聊天逻辑
},
contentAlignment = Alignment.Center
) {
Text(
text = "聊天",
fontSize = 12.sp,
color = AppColors.text,
fontWeight = androidx.compose.ui.text.font.FontWeight.W500
)
}
}
}
@Composable
@@ -275,9 +275,9 @@ fun Explore() {
) { page ->
// 计算当前页面的偏移量
val pageOffset = (
(pagerState.currentPage - page) + pagerState
.currentPageOffsetFraction
).coerceIn(-1f, 1f)
(pagerState.currentPage - page) + pagerState
.currentPageOffsetFraction
).coerceIn(-1f, 1f)
// 根据偏移量计算缩放比例
val scale = 1f - (0.1f * kotlin.math.abs(pageOffset))
@@ -473,22 +473,22 @@ fun Explore() {
verticalArrangement = androidx.compose.foundation.layout.Arrangement.SpaceBetween
) {
// 顶部:用户数量
Row(
Row(
verticalAlignment = Alignment.CenterVertically
) {
/* Image(
painter = painterResource(R.drawable.rider_pro_nav_profile),
contentDescription = "chat",
modifier = Modifier.size(16.dp),
colorFilter = ColorFilter.tint(Color.White)
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = "${bannerItem.userCount}人在聊",
fontSize = 12.sp,
color = Color.White,
fontWeight = androidx.compose.ui.text.font.FontWeight.W500
)*/
/* Image(
painter = painterResource(R.drawable.rider_pro_nav_profile),
contentDescription = "chat",
modifier = Modifier.size(16.dp),
colorFilter = ColorFilter.tint(Color.White)
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = "${bannerItem.userCount}人在聊",
fontSize = 12.sp,
color = Color.White,
fontWeight = androidx.compose.ui.text.font.FontWeight.W500
)*/
}
// 底部:标题和描述
@@ -500,7 +500,7 @@ fun Explore() {
overflow = androidx.compose.ui.text.style.TextOverflow.Ellipsis,
fontWeight = androidx.compose.ui.text.font.FontWeight.Bold,
color = Color.White,
modifier = Modifier.padding(start = 16.dp)
modifier = Modifier.padding(start = 16.dp)
)
Spacer(modifier = Modifier.height(8.dp))
Text(
@@ -516,81 +516,81 @@ fun Explore() {
Row(
modifier = Modifier.fillMaxWidth()
.background(brush = androidx.compose.ui.graphics.Brush.verticalGradient(
colors = listOf(
Color(0x00000000), // 底部颜色(透明)
Color(0x33000000), // 顶部颜色
colors = listOf(
Color(0x00000000), // 底部颜色(透明)
Color(0x33000000), // 顶部颜色
)
)),
)
)),
horizontalArrangement = androidx.compose.foundation.layout.Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row( modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically){
// 左侧头像
Box(
modifier = Modifier
.size(24.dp)
.background(
Color.White.copy(alpha = 0.2f),
RoundedCornerShape(16.dp)
)
) {
CustomAsyncImage(
context = context,
imageUrl = bannerItem.imageUrl,
contentDescription = "agent Image",
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
.clip(RoundedCornerShape(24.dp)))
}
// 中间信息区域占比1
Column(
modifier = Modifier
.weight(1f)
.padding(horizontal = 8.dp)
) {
Text(
text = bannerItem.agentName,
fontSize = 10.sp,
color = Color(0xfff5f5f5).copy(alpha = 0.6f),
fontWeight = androidx.compose.ui.text.font.FontWeight.W500
verticalAlignment = Alignment.CenterVertically){
// 左侧头像
Box(
modifier = Modifier
.size(24.dp)
.background(
Color.White.copy(alpha = 0.2f),
RoundedCornerShape(16.dp)
)
Text(
text = bannerItem.subtitle,
fontSize = 12.sp,
color = Color.White,
maxLines = 1,
fontWeight = androidx.compose.ui.text.font.FontWeight.W400,
modifier = Modifier.padding(top = 2.dp)
)
}
// 右侧进入按钮
Box(
modifier = Modifier
.width(69.dp)
.height(29.dp)
.background(
color = Color(0x7dffffff),
shape = RoundedCornerShape(8.dp)
)
.clickable {
// 进入房间逻辑
},
contentAlignment = Alignment.Center
) {
Text(
text = "进入",
fontSize = 14.sp,
color = Color.White,
fontWeight = androidx.compose.ui.text.font.FontWeight.W600
) {
CustomAsyncImage(
context = context,
imageUrl = bannerItem.imageUrl,
contentDescription = "agent Image",
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
.clip(RoundedCornerShape(24.dp)))
}
// 中间信息区域占比1
Column(
modifier = Modifier
.weight(1f)
.padding(horizontal = 8.dp)
) {
Text(
text = bannerItem.agentName,
fontSize = 10.sp,
color = Color(0xfff5f5f5).copy(alpha = 0.6f),
fontWeight = androidx.compose.ui.text.font.FontWeight.W500
)
Text(
text = bannerItem.subtitle,
fontSize = 12.sp,
color = Color.White,
maxLines = 1,
fontWeight = androidx.compose.ui.text.font.FontWeight.W400,
modifier = Modifier.padding(top = 2.dp)
)
}
// 右侧进入按钮
Box(
modifier = Modifier
.width(69.dp)
.height(29.dp)
.background(
color = Color(0x7dffffff),
shape = RoundedCornerShape(8.dp)
)
}
.clickable {
// 进入房间逻辑
},
contentAlignment = Alignment.Center
) {
Text(
text = "进入",
fontSize = 14.sp,
color = Color.White,
fontWeight = androidx.compose.ui.text.font.FontWeight.W600
)
}
}
@@ -706,7 +706,7 @@ fun Explore() {
contentDescription = "发布动态",
modifier = Modifier.size(24.dp),
)
)
}
Spacer(modifier = Modifier.size(8.dp))
Text(
@@ -733,7 +733,7 @@ fun Explore() {
contentDescription = "热门智能体",
modifier = Modifier.size(24.dp),
)
)
}
Spacer(modifier = Modifier.size(8.dp))
Text(
@@ -746,96 +746,96 @@ fun Explore() {
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun BannerSection(bannerItems: List<BannerItem>) {
val AppColors = LocalAppTheme.current
val context = LocalContext.current
val scope = rememberCoroutineScope()
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun BannerSection(bannerItems: List<BannerItem>) {
val AppColors = LocalAppTheme.current
val context = LocalContext.current
val scope = rememberCoroutineScope()
val pagerState = rememberPagerState(pageCount = { bannerItems.size })
val pagerState = rememberPagerState(pageCount = { bannerItems.size })
// 预加载banner图片
LaunchedEffect(bannerItems) {
bannerItems.forEach { bannerItem ->
if (bannerItem.backgroundImageUrl.isNotEmpty()) {
// 预加载背景图片
com.aiosman.ravenow.utils.Utils.getImageLoader(context).enqueue(
coil.request.ImageRequest.Builder(context)
.data(bannerItem.backgroundImageUrl)
.memoryCachePolicy(coil.request.CachePolicy.ENABLED)
.diskCachePolicy(coil.request.CachePolicy.ENABLED)
.build()
)
}
if (bannerItem.imageUrl.isNotEmpty()) {
// 预加载头像图片
com.aiosman.ravenow.utils.Utils.getImageLoader(context).enqueue(
coil.request.ImageRequest.Builder(context)
.data(bannerItem.imageUrl)
.memoryCachePolicy(coil.request.CachePolicy.ENABLED)
.diskCachePolicy(coil.request.CachePolicy.ENABLED)
.build()
)
}
}
}
Column {
// Banner内容
Box(
modifier = Modifier
.fillMaxWidth()
.height(362.dp)
) {
HorizontalPager(
state = pagerState,
modifier = Modifier.fillMaxSize(),
contentPadding = androidx.compose.foundation.layout.PaddingValues(horizontal = 4.dp),
) { page ->
val bannerItem = bannerItems[page]
// 计算当前页面的偏移量
val pageOffset = (
(pagerState.currentPage - page) + pagerState
.currentPageOffsetFraction
).coerceIn(-1f, 1f)
// 根据偏移量计算缩放比例
val scale = 1f - (0.1f * kotlin.math.abs(pageOffset))
BannerCard(
bannerItem = bannerItem,
modifier = Modifier
.graphicsLayer {
scaleX = scale
scaleY = scale
}
)
}
}
// 指示器
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 12.dp),
horizontalArrangement = androidx.compose.foundation.layout.Arrangement.Center
) {
bannerItems.forEachIndexed { index, _ ->
Box(
modifier = Modifier
.padding(horizontal = 4.dp)
.size(3.dp)
.background(
color = if (pagerState.currentPage == index) AppColors.main else AppColors.secondaryText.copy(alpha = 0.3f),
shape = androidx.compose.foundation.shape.CircleShape
)
)
}
}
}
// 预加载banner图片
LaunchedEffect(bannerItems) {
bannerItems.forEach { bannerItem ->
if (bannerItem.backgroundImageUrl.isNotEmpty()) {
// 预加载背景图片
com.aiosman.ravenow.utils.Utils.getImageLoader(context).enqueue(
coil.request.ImageRequest.Builder(context)
.data(bannerItem.backgroundImageUrl)
.memoryCachePolicy(coil.request.CachePolicy.ENABLED)
.diskCachePolicy(coil.request.CachePolicy.ENABLED)
.build()
)
}
if (bannerItem.imageUrl.isNotEmpty()) {
// 预加载头像图片
com.aiosman.ravenow.utils.Utils.getImageLoader(context).enqueue(
coil.request.ImageRequest.Builder(context)
.data(bannerItem.imageUrl)
.memoryCachePolicy(coil.request.CachePolicy.ENABLED)
.diskCachePolicy(coil.request.CachePolicy.ENABLED)
.build()
)
}
}
}
Column {
// Banner内容
Box(
modifier = Modifier
.fillMaxWidth()
.height(362.dp)
) {
HorizontalPager(
state = pagerState,
modifier = Modifier.fillMaxSize(),
contentPadding = androidx.compose.foundation.layout.PaddingValues(horizontal = 4.dp),
) { page ->
val bannerItem = bannerItems[page]
// 计算当前页面的偏移量
val pageOffset = (
(pagerState.currentPage - page) + pagerState
.currentPageOffsetFraction
).coerceIn(-1f, 1f)
// 根据偏移量计算缩放比例
val scale = 1f - (0.1f * kotlin.math.abs(pageOffset))
BannerCard(
bannerItem = bannerItem,
modifier = Modifier
.graphicsLayer {
scaleX = scale
scaleY = scale
}
)
}
}
// 指示器
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 12.dp),
horizontalArrangement = androidx.compose.foundation.layout.Arrangement.Center
) {
bannerItems.forEachIndexed { index, _ ->
Box(
modifier = Modifier
.padding(horizontal = 4.dp)
.size(3.dp)
.background(
color = if (pagerState.currentPage == index) AppColors.main else AppColors.secondaryText.copy(alpha = 0.3f),
shape = androidx.compose.foundation.shape.CircleShape
)
)
}
}
}
}
// 第二块区域Banner
@@ -886,7 +886,7 @@ fun Explore() {
contentDescription = "agent",
modifier = Modifier.size(28.dp),
)
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = "推荐给你的智能体",

View File

@@ -112,7 +112,7 @@
<string name="close">Close</string>
<string name="blocked">Blocked</string>
<string name="feedback">Feedback</string>
<string name="about_rave_now">About Rave Now</string>
<string name="about_rave_now">About Rave Now </string>
<string name="account_and_security">Account and security</string>
<string name="remove_account">Remove Account</string>
<string name="remove_account_desc">Are you sure you want to remove your account? This action cannot be undone.</string>