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

Jetpack Compose实现两个自定义图片按钮互斥切换问题

解决Jetpack Compose中两个IconToggleButton互斥的问题

问题根源在于你当前的每个按钮独立维护自身状态,导致无法实现互斥逻辑。解决核心是状态提升——将选中状态放到父组件统一管理,让两个按钮共享同一状态源。

修改后的完整代码

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ButtonSwitchSweetVibrationsTheme {
                CompactView()
            }
        }
    }
}

@Composable
fun CompactView() {
    // 用0表示未选中,1表示第一个按钮,2表示第二个按钮
    var selectedButton by remember { mutableStateOf(0) }
    val textPadding = Modifier.padding(8.dp)
    val textColor = Color.White

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(color = Yellow)
    ) {
        Column(
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Top,
        ) {
            Image(
                modifier = Modifier
                    .padding(0.dp, 15.dp, 0.dp, 75.dp)
                    .background(color = Red),
                painter = painterResource(id = R.drawable.sweetlogo),
                contentDescription = "border",
            )

            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .background(Color.Green),
                horizontalArrangement = Arrangement.SpaceEvenly,
            ) {
                // 第一个按钮组
                Column(
                    modifier = Modifier.background(Color.LightGray),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text(text = "First Button", modifier = textPadding, color = textColor)
                    ToggleImageButton(
                        checked = selectedButton == 1,
                        onCheckedChange = { isChecked ->
                            selectedButton = if (isChecked) 1 else 0
                        },
                        normalImage = R.drawable.copperbutton,
                        checkedImage = R.drawable.copperbuttonclicked,
                        contentDesc = "Classic Vibration"
                    )
                }

                // 第二个按钮组
                Column(
                    modifier = Modifier.background(Color.LightGray),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Text(text = "Second Button", modifier = textPadding, color = textColor)
                    ToggleImageButton(
                        checked = selectedButton == 2,
                        onCheckedChange = { isChecked ->
                            selectedButton = if (isChecked) 2 else 0
                        },
                        // 替换为第二个按钮的对应图片资源
                        normalImage = R.drawable.secondbutton,
                        checkedImage = R.drawable.secondbuttonclicked,
                        contentDesc = "Hump Vibration"
                    )
                }
            }
        }
    }
}

// 通用的图片切换按钮组件
@Composable
fun ToggleImageButton(
    checked: Boolean,
    onCheckedChange: (Boolean) -> Unit,
    normalImage: Int,
    checkedImage: Int,
    contentDesc: String
) {
    IconToggleButton(
        modifier = Modifier.size(125.dp),
        checked = checked,
        onCheckedChange = onCheckedChange
    ) {
        // 根据选中状态切换图片,避免原代码中图片叠加的问题
        Image(
            modifier = Modifier.fillMaxSize(),
            painter = painterResource(
                id = if (checked) checkedImage else normalImage
            ),
            contentDescription = contentDesc
        )
    }
}

关键说明

  1. 状态统一管理:在父组件CompactView中定义selectedButton变量,用不同数值标记选中状态,两个按钮通过判断该变量的值确定自身是否激活。
  2. 通用组件复用:封装ToggleImageButton组件,将按钮逻辑、图片切换逻辑抽离,只需传入不同的图片资源和状态判断条件即可复用。
  3. 修复图片叠加问题:原代码中两个Image同时渲染会导致叠加,现在通过if-else逻辑确保同一时间只显示一张图片。

如果需要强制保持一个按钮选中(点击已选中按钮无反应),可以修改回调逻辑为:

onCheckedChange = {
    selectedButton = if (selectedButton != 1) 1 else selectedButton
}

内容的提问来源于stack exchange,提问作者Casey Y.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:47:31