Jetpack Compose中实现每3次点击触发AdMob插页广告
Jetpack Compose实现AdMob插页广告每3次点击展示一次的逻辑
核心思路是用持久化计数器跟踪点击次数,每次点击递增计数器,当计数器达到3时展示广告,随后重置计数器进入下一轮循环。需要注意计数器的状态要能在Compose重组、配置变化(如屏幕旋转)时保留,推荐用ViewModel管理状态,单个Composable内也可以用remember临时保存。
方案一:用ViewModel管理状态(推荐)
ViewModel能在配置变化时保留状态,适合跨页面或需要持久化的场景:
import android.content.Context import com.google.android.gms.ads.AdRequest import com.google.android.gms.ads.InterstitialAd import com.google.android.gms.ads.LoadAdError import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.launch class AdManagerViewModel : ViewModel() { private var clickCounter = 0 private var interstitialAd: InterstitialAd? = null // 初始化时预加载广告 fun initAd(context: Context) { loadInterstitialAd(context) } // 处理点击事件 fun handleButtonClick(context: Context) { clickCounter++ if (clickCounter == 3) { interstitialAd?.let { ad -> if (ad.isLoaded) { ad.show() // 展示后重置计数器,同时预加载下一个广告 clickCounter = 0 loadInterstitialAd(context) } else { // 广告未加载完成,不重置计数器,等待下次点击 clickCounter-- } } ?: run { // 广告实例为空,重新加载,不重置计数器 clickCounter-- loadInterstitialAd(context) } } } // 加载插页广告 private fun loadInterstitialAd(context: Context) { InterstitialAd.load( context, "你的广告单元ID", // 替换为你的AdMob插页广告ID AdRequest.Builder().build(), object : com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback() { override fun onAdLoaded(ad: InterstitialAd) { interstitialAd = ad } override fun onAdFailedToLoad(adError: LoadAdError) { interstitialAd = null // 可选:广告加载失败后重试,注意控制重试次数 viewModelScope.launch { kotlinx.coroutines.delay(2000) loadInterstitialAd(context) } } } ) } }
在Compose页面中使用:
@Composable fun MainScreen( viewModel: AdManagerViewModel = viewModel() ) { // 页面初始化时加载广告 LaunchedEffect(Unit) { viewModel.initAd(LocalContext.current) } Button( onClick = { viewModel.handleButtonClick(LocalContext.current) } ) { Text(text = "点击触发操作") } }
方案二:单个Composable内用remember临时保存状态
如果仅在单个Composable内使用,不需要跨页面或持久化状态,可以用remember:
@Composable fun AdDemoScreen() { val context = LocalContext.current val clickCounter = remember { mutableStateOf(0) } val interstitialAd = remember { mutableStateOf<InterstitialAd?>(null) } // 初始化加载广告 LaunchedEffect(Unit) { loadInterstitialAd(context) { ad -> interstitialAd.value = ad } } Button( onClick = { clickCounter.value++ if (clickCounter.value == 3) { interstitialAd.value?.let { ad -> if (ad.isLoaded) { ad.show() clickCounter.value = 0 // 预加载下一个广告 loadInterstitialAd(context) { newAd -> interstitialAd.value = newAd } } else { clickCounter.value-- // 广告未加载,回退计数器 } } ?: run { clickCounter.value-- loadInterstitialAd(context) { newAd -> interstitialAd.value = newAd } } } } ) { Text(text = "点击测试") } } // 单独的广告加载函数 private fun loadInterstitialAd( context: Context, onAdLoaded: (InterstitialAd) -> Unit ) { InterstitialAd.load( context, "你的广告单元ID", AdRequest.Builder().build(), object : com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback() { override fun onAdLoaded(ad: InterstitialAd) { onAdLoaded(ad) } override fun onAdFailedToLoad(adError: LoadAdError) { // 可选:加载失败重试 } } ) }
关键注意事项
- 广告预加载:务必在页面初始化时就加载第一个广告,保证首次达到点击阈值时能正常展示。
- 计数器回退逻辑:如果广告未加载完成,不要重置计数器,避免用户多次点击却看不到广告。
- 合规性:遵循AdMob的政策,不要过度展示广告,避免影响用户体验导致账号违规。
- 配置变化兼容:如果需要在屏幕旋转等配置变化后保留计数器状态,必须用ViewModel,
remember会在重组时丢失状态。
内容的提问来源于stack exchange,提问作者oolyvi
相关产品推荐
相关产品推荐

