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

Android中如何防止主题切换按钮重复点击导致插屏广告多次弹出

解决Compose主题切换图标多次弹出插屏广告的问题

问题场景

在使用Compose的IconToggleButton实现主题切换时,集成了插屏广告,但用户快速点击图标会导致广告多次弹出,严重影响体验。需要实现点击后直到广告流程完全结束,按钮才允许再次被点击的控制逻辑。

原代码片段

var isDarkMode by remember { mutableStateOf(isSystemInDarkTheme) }

IconToggleButton(
    checked = isDarkMode,
    onCheckedChange = { isChecked ->
        isDarkMode = isChecked

        if (activity != null) {
            showInterstialAd(activity, context)
        }

        changeThemeViewModel.enableDarkTheme(isDarkMode)
    },
    modifier = Modifier.pulsateClick()
) {
    Icon(
        painter = painterResource(R.drawable.icon),
        contentDescription = stringResource(R.string.lamp_icon),
        modifier = Modifier
            .size(45.dp)   
    )
}

解决方案

核心思路是新增一个状态变量跟踪广告的展示状态,以此控制按钮的可交互性,并在广告生命周期结束后重置状态。

步骤1:添加广告展示状态变量

在remember块中新增isAdShowing状态,用于标记当前是否有广告正在展示:

var isDarkMode by remember { mutableStateOf(isSystemInDarkTheme) }
// 新增:跟踪广告是否正在展示
var isAdShowing by remember { mutableStateOf(false) }

步骤2:控制按钮的可点击性

修改IconToggleButton的enabled参数,同时在onCheckedChange中增加状态判断,避免重复触发广告:

IconToggleButton(
    checked = isDarkMode,
    // 关键:广告展示时禁用按钮,从UI层面阻止重复点击
    enabled = !isAdShowing,
    onCheckedChange = { isChecked ->
        isDarkMode = isChecked
        changeThemeViewModel.enableDarkTheme(isDarkMode)

        if (activity != null && !isAdShowing) {
            isAdShowing = true
            showInterstialAd(activity, context) {
                // 广告关闭后重置状态,允许再次点击
                isAdShowing = false
            }
        }
    },
    modifier = Modifier.pulsateClick()
) {
    Icon(
        painter = painterResource(R.drawable.icon),
        contentDescription = stringResource(R.string.lamp_icon),
        modifier = Modifier.size(45.dp)   
    )
}

步骤3:改造广告展示函数

给showInterstialAd添加回调参数,确保在广告所有结束场景(关闭、加载失败等)都能重置按钮状态:

// 改造后的广告展示函数示例
fun showInterstialAd(activity: Activity, context: Context, onAdClosed: () -> Unit) {
    val interstitialAd = InterstitialAd(context)
    interstitialAd.adUnitId = "你的广告ID"
    
    interstitialAd.adListener = object : AdListener() {
        override fun onAdClosed() {
            super.onAdClosed()
            // 广告正常关闭时触发回调
            onAdClosed.invoke()
        }

        override fun onAdFailedToLoad(errorCode: Int) {
            super.onAdFailedToLoad(errorCode)
            // 广告加载失败也要重置状态,避免按钮永久禁用
            onAdClosed.invoke()
        }
    }

    interstitialAd.loadAd(AdRequest.Builder().build())
}

关键说明

  • enabled = !isAdShowing:直接禁用按钮,用户在广告展示期间无法点击,从UI层面彻底避免重复触发。
  • 广告全场景回调:无论广告是正常关闭还是加载失败,都能通过回调重置状态,防止按钮永久失效。
  • 双重状态判断:即使UI禁用逻辑意外失效,代码层面的!isAdShowing判断也能阻止重复调用广告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:57:18