在我的 Android 应用程序中,我使用 Google 地图并在地图上显示标记。当用户单击其中一个标记时,我想打开一个模式底部表来显示标记详细信息。 我应该在哪里实现工作表代码,在最顶层的可组合项中还是在显示标记的标记可组合项中?
快速打开模态表的最佳方法是什么?
这是我目前正在做的事情:
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun A() {
// Sheet state should be handled at the highest relevant level
val sheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = false
)
var showBottomSheet by remember { mutableStateOf(false) }
var selectedMarker by remember { mutableStateOf<MarkerData?>(null) }
// Handler to be passed down
val onMarkerClick: (MarkerData) -> Unit = { markerData ->
selectedMarker = markerData
showBottomSheet = true
}
// Main content
Box(modifier = Modifier.fillMaxSize()) {
Maps(onMarkerClick = onMarkerClick)
// BottomSheet
if (showBottomSheet) {
ModalBottomSheet(
onDismissRequest = {
showBottomSheet = false
selectedMarker = null
},
sheetState = sheetState
) {
// Sheet content
MarkerDetailContent(
markerData = selectedMarker,
onDismiss = {
showBottomSheet = false
selectedMarker = null
}
)
}
}
}
}
@Composable
fun Maps(
onMarkerClick: (MarkerData) -> Unit
) {
// Map implementation
GoogleMap(
modifier = Modifier.fillMaxSize(),
properties = MapProperties(/*...*/)
) {
Markers(onMarkerClick = onMarkerClick)
}
}
@Composable
fun Markers(
onMarkerClick: (MarkerData) -> Unit
) {
// Marker data (could come from ViewModel)
val markers = remember { /* Your markers data */ }
markers.forEach { markerData ->
Marker(
state = rememberMarkerState(
position = markerData.position
),
onClick = {
onMarkerClick(markerData)
true // consume the event
}
)
}
}
@Composable
fun MarkerDetailContent(
markerData: MarkerData?,
onDismiss: () -> Unit
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
text = "Marker Details",
style = MaterialTheme.typography.headlineSmall,
modifier = Modifier.padding(bottom = 16.dp)
)
markerData?.let {
Text("Title: ${it.title}")
Text("Position: ${it.position}")
// Add more marker details
}
Spacer(modifier = Modifier.height(16.dp))
Button(
onClick = onDismiss,
modifier = Modifier.fillMaxWidth()
) {
Text("Close")
}
}
}
// Data class for markers
data class MarkerData(
val id: String,
val title: String,
val position: LatLng,
// Add other marker properties
)
从技术上讲,你在哪里调用它并不重要,因为它总是显示在整个屏幕上方。不过,我想说你的实施方式是一个很好的做法。由于
ModalBottomSheet
在语义上影响整个屏幕,我也宁愿将其放置在顶级可组合项中。
请注意,您当前如何实现
ModalBottomSheet
,当您按下带有标签Button
的"Close"
时,它将立即隐藏,没有任何动画。相反,首先 hide()
它,然后相应地更新 showBottomSheet
变量:
val scope = rememberCoroutineScope() // on top of Composable, add this line
//...
MarkerDetailContent(
markerData = selectedMarker,
onDismiss = {
scope.launch {
sheetState.hide() // hide BottomSheet with animation
}.invokeOnCompletion {
if (!bottomSheetState.isVisible) {
showBottomSheet = false // update variable afterwards
selectedMarker = null
}
}
}
)