package com.aiosman.riderpro import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.ScrollableDefaults import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.PaddingValues 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.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells import androidx.compose.foundation.lazy.staggeredgrid.items import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Favorite import androidx.compose.material.icons.filled.LocationOn import androidx.compose.material3.BottomSheetScaffold import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SheetState import androidx.compose.material3.SheetValue import androidx.compose.material3.Text import androidx.compose.material3.rememberBottomSheetScaffoldState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow 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.layout.ContentScale import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import kotlinx.coroutines.launch data class OfficialGalleryItem( val id: Int, val resId: Int, ) fun getOfficialGalleryItems(): List { return listOf( OfficialGalleryItem(1, R.drawable.default_moment_img), OfficialGalleryItem(2, R.drawable.default_moment_img), OfficialGalleryItem(3, R.drawable.default_moment_img), OfficialGalleryItem(4, R.drawable.default_moment_img), OfficialGalleryItem(5, R.drawable.default_moment_img), OfficialGalleryItem(6, R.drawable.default_moment_img), OfficialGalleryItem(7, R.drawable.default_moment_img), OfficialGalleryItem(8, R.drawable.default_moment_img), OfficialGalleryItem(9, R.drawable.default_moment_img), OfficialGalleryItem(10, R.drawable.default_moment_img), OfficialGalleryItem(11, R.drawable.default_moment_img), OfficialGalleryItem(12, R.drawable.default_moment_img), OfficialGalleryItem(13, R.drawable.default_moment_img), OfficialGalleryItem(14, R.drawable.default_moment_img), OfficialGalleryItem(15, R.drawable.default_moment_img), OfficialGalleryItem(16, R.drawable.default_moment_img), OfficialGalleryItem(17, R.drawable.default_moment_img), OfficialGalleryItem(18, R.drawable.default_moment_img), OfficialGalleryItem(19, R.drawable.default_moment_img), OfficialGalleryItem(20, R.drawable.default_moment_img), ) } data class FeedItem( val id: Int, val resId: Int, ) fun getFeedItems(): List { val image_pickups = listOf( R.drawable.default_moment_img, R.drawable.default_avatar, R.drawable.rider_pro_moment_demo_1, R.drawable.rider_pro_moment_demo_2, R.drawable.rider_pro_moment_demo_3, ) return (1..100).map { FeedItem(it, image_pickups.random()) } } @OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class) @Preview @Composable fun LocationDetail() { val scope = rememberCoroutineScope() val scaffoldState = rememberBottomSheetScaffoldState( SheetState( skipPartiallyExpanded = false, density = LocalDensity.current, initialValue = SheetValue.PartiallyExpanded, skipHiddenState = true ) ) val configuration = LocalConfiguration.current val officialGalleryItems = getOfficialGalleryItems() val feedItems = getFeedItems() val navController = LocalNavController.current // 2/3 height of the screen fun getPeekHeight(): Dp { val screenHeight = configuration.screenHeightDp val peekHeight = (screenHeight * 2 / 3).dp return peekHeight } fun getNoPeekHeight(): Dp { val screenHeight = configuration.screenHeightDp val peekHeight = (screenHeight * 1 / 3).dp return peekHeight } Box( modifier = Modifier.fillMaxSize() ) { Image( painter = painterResource(id = R.drawable.default_moment_img), contentDescription = "Location Image", modifier = Modifier .fillMaxWidth() .height(getNoPeekHeight() + 100.dp), contentScale = ContentScale.Crop ) val bottomSheetScaffoldState = rememberBottomSheetScaffoldState() BottomSheetScaffold( scaffoldState = scaffoldState, sheetPeekHeight = getPeekHeight(), sheetShadowElevation = 0.dp, sheetContainerColor = Color.Transparent, sheetShape = RoundedCornerShape(16.dp, 16.dp, 0.dp, 0.dp), sheetDragHandle = null, sheetContent = { Column( Modifier .fillMaxWidth() .background(color = Color.White) ) { Column( modifier = Modifier .padding(horizontal = 16.dp) ) { Spacer(modifier = Modifier.height(12.dp)) // 自定义短线 Box( modifier = Modifier .width(32.dp) // 修改宽度 .height(4.dp) // 修改高度 .background(Color(0f,0f,0f,0.4f), RoundedCornerShape(3.dp)) // 修改颜色和圆角 .padding(top = 12.dp) // 调整位置 .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( modifier = Modifier .fillMaxWidth() .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 .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 16.dp) ) { Text("车友动态", fontSize = 16.sp, fontWeight = FontWeight.Bold) } LazyVerticalStaggeredGrid( columns = StaggeredGridCells.Fixed(2), // Set to 2 columns modifier = Modifier.fillMaxSize(), state = rememberLazyStaggeredGridState(), contentPadding = PaddingValues(16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp), flingBehavior = ScrollableDefaults.flingBehavior(), ) { items(feedItems) { item -> Column( modifier = Modifier .fillMaxWidth() .padding(bottom = 16.dp) ) { Image( painter = painterResource(id = item.resId), contentDescription = "Feed", modifier = Modifier.fillMaxWidth() .clip(MaterialTheme.shapes.medium).clickable { navController.navigate("Post") }, contentScale = ContentScale.FillWidth ) Spacer(modifier = Modifier.height(8.dp)) Column( modifier = Modifier .fillMaxWidth() .padding(horizontal = 8.dp) ) { Box( modifier = Modifier.fillMaxWidth() ) { Text("Some text") } Spacer(modifier = Modifier.height(8.dp)) Row( verticalAlignment = Alignment.CenterVertically ) { Image( painter = painterResource(id = R.drawable.default_avatar), contentDescription = "Avatar", modifier = Modifier .size(18.dp) .clip(CircleShape), contentScale = ContentScale.Crop ) Spacer(modifier = Modifier.width(8.dp)) Text("Username", color = Color(0xFF666666), fontSize = 14.sp) Spacer(modifier = Modifier.weight(1f)) Icon( Icons.Filled.Favorite, contentDescription = "Location" ) Spacer(modifier = Modifier.width(4.dp)) Text("100K", fontSize = 14.sp) } } } } } } }, ) { } } }