新增 LocationDetail的折叠动画

This commit is contained in:
2024-07-17 09:46:16 +08:00
parent a6ba076591
commit 3f9bfb1254

View File

@@ -1,5 +1,7 @@
package com.aiosman.riderpro package com.aiosman.riderpro
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@@ -93,10 +95,12 @@ fun getOfficialGalleryItems(): List<OfficialGalleryItem> {
OfficialGalleryItem(20, R.drawable.default_moment_img), OfficialGalleryItem(20, R.drawable.default_moment_img),
) )
} }
data class FeedItem( data class FeedItem(
val id: Int, val id: Int,
val resId: Int, val resId: Int,
) )
fun getFeedItems(): List<FeedItem> { fun getFeedItems(): List<FeedItem> {
val image_pickups = listOf( val image_pickups = listOf(
R.drawable.default_moment_img, R.drawable.default_moment_img,
@@ -109,6 +113,7 @@ fun getFeedItems(): List<FeedItem> {
FeedItem(it, image_pickups.random()) FeedItem(it, image_pickups.random())
} }
} }
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Preview @Preview
@Composable @Composable
@@ -125,17 +130,30 @@ fun LocationDetail() {
val officialGalleryItems = getOfficialGalleryItems() val officialGalleryItems = getOfficialGalleryItems()
val feedItems = getFeedItems() val feedItems = getFeedItems()
val navController = LocalNavController.current val navController = LocalNavController.current
// 2/3 height of the screen // 2/3 height of the screen
fun getPeekHeight(): Dp { fun getPeekHeight(): Dp {
val screenHeight = configuration.screenHeightDp val screenHeight = configuration.screenHeightDp
val peekHeight = (screenHeight * 2 / 3).dp val peekHeight = (screenHeight * 2 / 3).dp
return peekHeight return peekHeight
} }
fun getNoPeekHeight(): Dp { fun getNoPeekHeight(): Dp {
val screenHeight = configuration.screenHeightDp val screenHeight = configuration.screenHeightDp
val peekHeight = (screenHeight * 1 / 3).dp val peekHeight = (screenHeight * 1 / 3).dp
return peekHeight return peekHeight
} }
val staggeredGridState = rememberLazyStaggeredGridState()
val coroutineScope = rememberCoroutineScope()
var showGalleryAndInfo by remember { mutableStateOf(true) }
LaunchedEffect(staggeredGridState) {
snapshotFlow { staggeredGridState.firstVisibleItemIndex }
.collect { index ->
// Assuming index 0 corresponds to the top of the feed
showGalleryAndInfo = index == 0
}
}
Box( Box(
modifier = Modifier.fillMaxSize() modifier = Modifier.fillMaxSize()
) { ) {
@@ -163,6 +181,7 @@ fun LocationDetail() {
) { ) {
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp) .padding(horizontal = 16.dp)
) { ) {
Spacer(modifier = Modifier.height(12.dp)) Spacer(modifier = Modifier.height(12.dp))
@@ -171,125 +190,47 @@ fun LocationDetail() {
modifier = Modifier modifier = Modifier
.width(32.dp) // 修改宽度 .width(32.dp) // 修改宽度
.height(4.dp) // 修改高度 .height(4.dp) // 修改高度
.background(Color(0f,0f,0f,0.4f), RoundedCornerShape(3.dp)) // 修改颜色和圆角 .background(
Color(0f, 0f, 0f, 0.4f),
RoundedCornerShape(3.dp)
) // 修改颜色和圆角
.padding(top = 12.dp) // 调整位置 .padding(top = 12.dp) // 调整位置
.align(Alignment.CenterHorizontally) .align(Alignment.CenterHorizontally)
) )
Text("Location Name", modifier = Modifier.padding(top = 24.dp), fontSize = 18.sp, fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.height(8.dp))
FlowRow(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
repeat(10) {
Box(
modifier = Modifier
.background(Color(0xFFF5F5F5))
.padding(horizontal = 7.dp, vertical = 2.dp)
) {
Text("Tag $it", color = Color(0xFFb2b2b2), fontSize = 12.sp)
}
}
}
HorizontalDivider(
modifier = Modifier.padding(top = 16.dp),
color = Color(0xFFF5F5F5)
)
Row(
modifier = Modifier.padding(vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Column {
Text(
"Location name",
fontSize = 14.sp,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(8.dp))
Text("距离46KM,骑行时间77分钟",fontSize = 12.sp)
}
Spacer(modifier = Modifier.weight(1f))
Image(painter = painterResource(id = R.drawable.rider_pro_location_map), contentDescription = "")
}
} }
Box( GalleryAndInfo(showGalleryAndInfo)
modifier = Modifier // feed
.fillMaxWidth() Row(
.height(8.dp)
.background(Color(0xFFF5F5F5))
)
Column(
modifier = Modifier
.padding(horizontal = 16.dp)
.padding(top = 18.dp)
) {
Row {
Text("官方摄影师作品", fontSize = 15.sp, fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.weight(1f))
Image(
painter = painterResource(id = R.drawable.rider_pro_nav_next),
contentDescription = "Next",
modifier = Modifier
.size(24.dp)
.clickable {
navController.navigate("OfficialPhoto")
}
)
}
Spacer(modifier = Modifier.height(17.dp))
Row(
modifier = Modifier.height(232.dp)
) {
Box(
modifier = Modifier.weight(1f)
) {
Image(
painter = painterResource(id = R.drawable.default_avatar),
contentDescription = "Avatar",
modifier = Modifier
.fillMaxSize()
.clip(RoundedCornerShape(16.dp)),
contentScale = ContentScale.Crop,
)
}
Spacer(modifier = Modifier.width(16.dp))
Box(
modifier = Modifier.weight(1f)
) {
Image(
painter = painterResource(id = R.drawable.default_avatar),
contentDescription = "Avatar",
modifier = Modifier
.fillMaxSize()
.clip(RoundedCornerShape(16.dp)),
contentScale = ContentScale.Crop
)
}
}
}
Spacer(modifier = Modifier.height(16.dp))
Box(
modifier = Modifier
.fillMaxWidth()
.height(8.dp)
.background(Color(0xFFF5F5F5))
)
Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 16.dp) .padding(horizontal = 16.dp, vertical = 16.dp)
.animateContentSize()
) { ) {
Text("车友动态", fontSize = 16.sp, fontWeight = FontWeight.Bold) AnimatedVisibility(visible = !showGalleryAndInfo) {
Row {
Icon(
Icons.Filled.LocationOn,
contentDescription = "Location",
modifier = Modifier.size(24.dp)
)
Spacer(modifier = Modifier.width(8.dp))
Text("在云龟山景区的", fontSize = 16.sp)
}
}
Text(
"车友动态",
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier.weight(1f)
)
} }
LazyVerticalStaggeredGrid( LazyVerticalStaggeredGrid(
columns = StaggeredGridCells.Fixed(2), // Set to 2 columns columns = StaggeredGridCells.Fixed(2), // Set to 2 columns
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
state = rememberLazyStaggeredGridState(), state = staggeredGridState,
contentPadding = PaddingValues(16.dp), contentPadding = PaddingValues(16.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp),
flingBehavior = ScrollableDefaults.flingBehavior(), flingBehavior = ScrollableDefaults.flingBehavior(),
@@ -303,8 +244,10 @@ fun LocationDetail() {
Image( Image(
painter = painterResource(id = item.resId), painter = painterResource(id = item.resId),
contentDescription = "Feed", contentDescription = "Feed",
modifier = Modifier.fillMaxWidth() modifier = Modifier
.clip(MaterialTheme.shapes.medium).clickable { .fillMaxWidth()
.clip(MaterialTheme.shapes.medium)
.clickable {
navController.navigate("Post") navController.navigate("Post")
}, },
contentScale = ContentScale.FillWidth contentScale = ContentScale.FillWidth
@@ -334,7 +277,11 @@ fun LocationDetail() {
contentScale = ContentScale.Crop contentScale = ContentScale.Crop
) )
Spacer(modifier = Modifier.width(8.dp)) Spacer(modifier = Modifier.width(8.dp))
Text("Username", color = Color(0xFF666666), fontSize = 14.sp) Text(
"Username",
color = Color(0xFF666666),
fontSize = 14.sp
)
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
Icon( Icon(
Icons.Filled.Favorite, Icons.Filled.Favorite,
@@ -359,6 +306,133 @@ fun LocationDetail() {
} }
} }
}
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun GalleryAndInfo(showGalleryAndInfo: Boolean) {
val navController = LocalNavController.current
Column(modifier = Modifier.animateContentSize()) {
AnimatedVisibility(visible = showGalleryAndInfo) {
Column {
// info panel
Column(
modifier = Modifier.padding(horizontal = 16.dp)
) {
Text(
"Location Name",
modifier = Modifier.padding(top = 24.dp),
fontSize = 18.sp,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(8.dp))
FlowRow(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
repeat(10) {
Box(
modifier = Modifier
.background(Color(0xFFF5F5F5))
.padding(horizontal = 7.dp, vertical = 2.dp)
) {
Text("Tag $it", color = Color(0xFFb2b2b2), fontSize = 12.sp)
}
}
}
HorizontalDivider(
modifier = Modifier.padding(top = 16.dp),
color = Color(0xFFF5F5F5)
)
Row(
modifier = Modifier.padding(vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Column {
Text(
"Location name",
fontSize = 14.sp,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(8.dp))
Text("距离46KM,骑行时间77分钟", fontSize = 12.sp)
}
Spacer(modifier = Modifier.weight(1f))
Image(
painter = painterResource(id = R.drawable.rider_pro_location_map),
contentDescription = ""
)
}
}
Box(
modifier = Modifier
.fillMaxWidth()
.height(8.dp)
.background(Color(0xFFF5F5F5))
)
// official gallery
Column(
modifier = Modifier
.padding(horizontal = 16.dp)
.padding(top = 18.dp)
) {
Row {
Text("官方摄影师作品", fontSize = 15.sp, fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.weight(1f))
Image(
painter = painterResource(id = R.drawable.rider_pro_nav_next),
contentDescription = "Next",
modifier = Modifier
.size(24.dp)
.clickable {
navController.navigate("OfficialPhoto")
}
)
}
Spacer(modifier = Modifier.height(17.dp))
Row(
modifier = Modifier.height(232.dp)
) {
Box(
modifier = Modifier.weight(1f)
) {
Image(
painter = painterResource(id = R.drawable.default_avatar),
contentDescription = "Avatar",
modifier = Modifier
.fillMaxSize()
.clip(RoundedCornerShape(16.dp)),
contentScale = ContentScale.Crop,
)
}
Spacer(modifier = Modifier.width(16.dp))
Box(
modifier = Modifier.weight(1f)
) {
Image(
painter = painterResource(id = R.drawable.default_avatar),
contentDescription = "Avatar",
modifier = Modifier
.fillMaxSize()
.clip(RoundedCornerShape(16.dp)),
contentScale = ContentScale.Crop
)
}
}
}
Spacer(modifier = Modifier.height(16.dp))
Box(
modifier = Modifier
.fillMaxWidth()
.height(8.dp)
.background(Color(0xFFF5F5F5))
)
}
}
}
} }