You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中如何正确实现点击TeamCard弹出对应链接的自定义AlertDialog

核心问题梳理
  • 现有代码仅存储了弹窗的开关布尔状态,未记录点击对应的球队数据,导致所有卡片点击都只能显示硬编码的固定链接
  • AppDialog的关闭逻辑未实际修改状态变量,点击关闭按钮/外部区域无法正常关闭弹窗
  • 跳转链接的功能未实现
具体实现方案

1. 优化TeamsScreen状态管理

将原来单独的弹窗开关状态,调整为存储可选的选中球队对象,通过对象是否为空控制弹窗显隐,同时可直接拿到对应球队的链接:

@Composable
fun TeamsScreen() {
    // 存储当前选中的球队,null表示弹窗未打开
    var selectedTeam by remember { mutableStateOf<Teams?>(null) }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(color = darkBackground),
        contentAlignment = Alignment.Center
    ) {
        // 仅当选中球队不为空时显示弹窗,传入对应球队的链接
        selectedTeam?.let { team ->
            AppDialog(
                link = team.officialLink, // 此处替换为你Teams类中对应链接的字段名即可
                dialogState = true,
                onDismissRequest = { selectedTeam = null },
                onDialogStateChange = { isOpen -> if (!isOpen) selectedTeam = null }
            )
        }
        Image(.. )
        Row(..) {
            Column(
                verticalArrangement = Arrangement.spacedBy(20.dp)
            ) {
                // 点击时把对应球队赋值给selectedTeam
                TeamCard(team = allTeamsLists[0]){ selectedTeam = allTeamsLists[0] }
                TeamCard(team = allTeamsLists[1]){ selectedTeam = allTeamsLists[1] }
                TeamCard(team = allTeamsLists[2]){ selectedTeam = allTeamsLists[2] }
            }
            Column(
                verticalArrangement = Arrangement.spacedBy(20.dp)
            ) {
                TeamCard(team = allTeamsLists[3]){ selectedTeam = allTeamsLists[3] }
                TeamCard(team = allTeamsLists[4]){ selectedTeam = allTeamsLists[4] }
            }
        }
    }
}

2. 修复AppDialog逻辑问题

补全关闭逻辑和跳转链接的实现,同时删除冗余的旋转代码:

@Composable
fun AppDialog(
    link: String,
    modifier: Modifier = Modifier,
    dialogState: Boolean = false,
    onDialogPositiveButtonClicked: (() -> Unit)? = null,
    onDialogStateChange: ((Boolean) -> Unit)? = null,
    onDismissRequest: (() -> Unit)? = null,
) {
    val buttonPaddingAll = 8.dp
    val dialogShape = RoundedCornerShape(16.dp)
    val context = LocalContext.current

    if (dialogState) {
        AlertDialog(
            onDismissRequest = {
                Toast.makeText(context, "outside dialog is clicked ", Toast.LENGTH_SHORT).show()
                // 关闭弹窗,通知状态变更
                onDialogStateChange?.invoke(false)
                onDismissRequest?.invoke()
            },
            title = null,
            text = null,
            buttons = {
                Row(
                    modifier = Modifier.padding(all = buttonPaddingAll),
                    horizontalArrangement = Arrangement.Center
                ) {
                    TextButton(
                        modifier = Modifier,
                        onClick = {
                            Toast.makeText(context, "link is clicked ", Toast.LENGTH_SHORT).show()
                            // 打开链接的逻辑,需要提前导入android.content.Intent和android.net.Uri
                            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(link))
                            context.startActivity(intent)
                            onDialogPositiveButtonClicked?.invoke()
                        }
                    ) {
                        Text(text = link, color = MaterialTheme.colors.onSurface)
                    }
                    Icon(
                        imageVector = Icons.Default.Add,
                        contentDescription = "关闭弹窗",
                        modifier = Modifier
                            .rotate(45f)
                            .clickable {
                                Toast.makeText(context, "cancel is clicked ", Toast.LENGTH_SHORT).show()
                                // 点击关闭按钮触发状态变更
                                onDialogStateChange?.invoke(false)
                                onDismissRequest?.invoke()
                            },
                        tint = Color.Black.copy(alpha = 0.8f)
                    )
                }
            },
            properties = DialogProperties(dismissOnBackPress = true, dismissOnClickOutside = true),
            modifier = modifier,
            shape = dialogShape
        )
    }
}

可选优化

当前手动拆分Column加载TeamCard的方式扩展性较差,如果后续球队数量增加,可以替换为LazyVerticalGrid实现自动网格排列,无需手动拆分多列。

内容的提问来源于stack exchange,提问作者Ashish Gautam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 17:36:04