在 Jetpack Compose 中哪里打开模式底部表单?

问题描述 投票:0回答:1

在我的 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
)
android android-jetpack-compose bottom-sheet modal-sheet
1个回答
0
投票

从技术上讲,你在哪里调用它并不重要,因为它总是显示在整个屏幕上方。不过,我想说你的实施方式是一个很好的做法。由于

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 
            }
        }
    }
)
© www.soinside.com 2019 - 2024. All rights reserved.