如何在 Jetpack Compose 中正确使用自定义 AlertDialog?
How to use custom AlertDialog properly in jetpack compose?
我有 TeamCard
只显示团队名称。
@Composable
fun TeamCard(team: Teams , openLink :()-> Unit) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
..
.clickable { openLink()}
) {
Row(
..
) {
..
}
}
}
我们有一个 TeamScreen
所有团队都在展示
@Composable
fun TeamsScreen() {
val openDialog = remember { mutableStateOf(false) }
Box(
modifier = Modifier
.fillMaxSize()
.background(color = darkBackground),
contentAlignment = Alignment.Center
) {
AppDialog( link = "https://www.fcbarcelona.com/en/ ", dialogState = openDialog.value)
Image(.. )
Row(..) {
Column(
verticalArrangement = Arrangement.spacedBy(20.dp)
) {
TeamCard(team = allTeamsLists[0]){openDialog.value = true }
TeamCard(team = allTeamsLists[1]){ openDialog.value = true}
TeamCard(team = allTeamsLists[2]){ openDialog.value = true}
}
Column(
verticalArrangement = Arrangement.spacedBy(20.dp)
) {
TeamCard(team = allTeamsLists[3]){}
TeamCard(team = allTeamsLists[4]){}
}
}
}
}
现在,当我想点击任何 TeamCard
时,应该会有一个带有 link 的自定义 AlertDialog
弹出窗口和十字按钮来关闭它。
@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(true)
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()
//Open link to web
}
) {
Text(text = link, color = MaterialTheme.colors.onSurface)
}
Icon(
imageVector = Icons.Default.Add.also { rotationMatrix(45f) },
contentDescription = null,
modifier = Modifier
.rotate(45f)
.clickable {
Toast.makeText(context, "cancle is clicked ", Toast.LENGTH_SHORT).show()
!dialogState
},
tint = Color.Black.copy(alpha = 0.8f)
)
}
},
properties = DialogProperties(dismissOnBackPress = true, dismissOnClickOutside = true),
modifier = modifier,
shape = dialogShape
)
}
}
并且allTeamsLists
有一个所有团队的列表link和团队名称关联的例子。
Teams( R.drawable.logo_1, "Real Madrid" , R.drawable.player1, "https://www.realmadrid.com/ " , R.drawable.blue_hands)
我无法正确设置,请建议我更好的方法。
此外,每次我单击特定的团队卡时,都会显示与其关联的 link 的警报。
您存储一个简单的布尔值,指示警报当前是否打开。如果您需要显示特定的 URL.
,此信息是不够的
相反,存储所选命令的可选 URL 并在不为空时显示警报。
我还建议您避免像现在这样重复代码。您可以使用 LazyVerticalGrid
:
而不是将多个 Column
-s 放入 Row
并手动填充它们
val dialogUrl by remember { mutableStateOf<String?>(null) }
if (dialogUrl != null) {
AppDialog(
dialogUrl,
onDismissRequest = {
dialogUrl = null
},
)
}
LazyVerticalGrid(
cells = GridCells.Fixed(3),
verticalArrangement = Arrangement.spacedBy(20.dp),
) {
items(allTeamsLists) { team ->
TeamCard(team = team){
dialogUrl = team.url
}
}
}
我有 TeamCard
只显示团队名称。
@Composable
fun TeamCard(team: Teams , openLink :()-> Unit) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
..
.clickable { openLink()}
) {
Row(
..
) {
..
}
}
}
我们有一个 TeamScreen
所有团队都在展示
@Composable
fun TeamsScreen() {
val openDialog = remember { mutableStateOf(false) }
Box(
modifier = Modifier
.fillMaxSize()
.background(color = darkBackground),
contentAlignment = Alignment.Center
) {
AppDialog( link = "https://www.fcbarcelona.com/en/ ", dialogState = openDialog.value)
Image(.. )
Row(..) {
Column(
verticalArrangement = Arrangement.spacedBy(20.dp)
) {
TeamCard(team = allTeamsLists[0]){openDialog.value = true }
TeamCard(team = allTeamsLists[1]){ openDialog.value = true}
TeamCard(team = allTeamsLists[2]){ openDialog.value = true}
}
Column(
verticalArrangement = Arrangement.spacedBy(20.dp)
) {
TeamCard(team = allTeamsLists[3]){}
TeamCard(team = allTeamsLists[4]){}
}
}
}
}
现在,当我想点击任何 TeamCard
时,应该会有一个带有 link 的自定义 AlertDialog
弹出窗口和十字按钮来关闭它。
@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(true)
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()
//Open link to web
}
) {
Text(text = link, color = MaterialTheme.colors.onSurface)
}
Icon(
imageVector = Icons.Default.Add.also { rotationMatrix(45f) },
contentDescription = null,
modifier = Modifier
.rotate(45f)
.clickable {
Toast.makeText(context, "cancle is clicked ", Toast.LENGTH_SHORT).show()
!dialogState
},
tint = Color.Black.copy(alpha = 0.8f)
)
}
},
properties = DialogProperties(dismissOnBackPress = true, dismissOnClickOutside = true),
modifier = modifier,
shape = dialogShape
)
}
}
并且allTeamsLists
有一个所有团队的列表link和团队名称关联的例子。
Teams( R.drawable.logo_1, "Real Madrid" , R.drawable.player1, "https://www.realmadrid.com/ " , R.drawable.blue_hands)
我无法正确设置,请建议我更好的方法。
此外,每次我单击特定的团队卡时,都会显示与其关联的 link 的警报。
您存储一个简单的布尔值,指示警报当前是否打开。如果您需要显示特定的 URL.
,此信息是不够的相反,存储所选命令的可选 URL 并在不为空时显示警报。
我还建议您避免像现在这样重复代码。您可以使用 LazyVerticalGrid
:
Column
-s 放入 Row
并手动填充它们
val dialogUrl by remember { mutableStateOf<String?>(null) }
if (dialogUrl != null) {
AppDialog(
dialogUrl,
onDismissRequest = {
dialogUrl = null
},
)
}
LazyVerticalGrid(
cells = GridCells.Fixed(3),
verticalArrangement = Arrangement.spacedBy(20.dp),
) {
items(allTeamsLists) { team ->
TeamCard(team = team){
dialogUrl = team.url
}
}
}