From 3b5637d4a0d7b867cba193f43a72aa3baf19c1c9 Mon Sep 17 00:00:00 2001 From: Nicholas Ventimiglia Date: Mon, 22 Jul 2024 16:31:45 -0700 Subject: [PATCH] Added Jetpack Compose Sample LazyList Banner. PiperOrigin-RevId: 654936228 --- .../app/src/main/AndroidManifest.xml | 2 +- .../GoogleMobileAdsApplication.kt | 2 +- .../GoogleMobileAdsConsentManager.kt | 2 +- .../jetpackcomposedemo/NavDestinations.kt | 6 - .../{ => formats}/BannerScreen.kt | 8 +- .../formats/LazyBannerScreen.kt | 190 ++++++++++++++++++ .../{ => main}/HomeScreen.kt | 11 +- .../{ => main}/MainActivity.kt | 3 +- .../{ => main}/MainScreen.kt | 16 +- .../{ => main}/MainUiState.kt | 2 +- .../{ => main}/MainViewModel.kt | 4 +- .../main/NavDestinations.kt | 7 + .../jetpackcomposedemo/ui/theme/Color.kt | 4 +- .../app/src/main/res/values/strings.xml | 12 ++ 14 files changed, 244 insertions(+), 25 deletions(-) delete mode 100644 kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/NavDestinations.kt rename kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/{ => formats}/BannerScreen.kt (94%) create mode 100644 kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/formats/LazyBannerScreen.kt rename kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/{ => main}/HomeScreen.kt (77%) rename kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/{ => main}/MainActivity.kt (91%) rename kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/{ => main}/MainScreen.kt (91%) rename kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/{ => main}/MainUiState.kt (87%) rename kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/{ => main}/MainViewModel.kt (95%) create mode 100644 kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/NavDestinations.kt diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/AndroidManifest.xml b/kotlin/advanced/JetpackComposeDemo/app/src/main/AndroidManifest.xml index 189cc7250..47b9d9d85 100644 --- a/kotlin/advanced/JetpackComposeDemo/app/src/main/AndroidManifest.xml +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/AndroidManifest.xml @@ -21,7 +21,7 @@ android:value="true" /> diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/GoogleMobileAdsApplication.kt b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/GoogleMobileAdsApplication.kt index 810f046e7..4d7e37677 100644 --- a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/GoogleMobileAdsApplication.kt +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/GoogleMobileAdsApplication.kt @@ -22,6 +22,6 @@ class GoogleMobileAdsApplication : Application() { companion object { const val TAG = "GoogleMobileAdsSample" - const val BANNER_ADUNIT_ID = "ca-app-pub-3940256099942544/9214589741" + const val BANNER_AD_UNIT_ID = "ca-app-pub-3940256099942544/9214589741" } } diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/GoogleMobileAdsConsentManager.kt b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/GoogleMobileAdsConsentManager.kt index 63c65816e..78b99c38c 100644 --- a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/GoogleMobileAdsConsentManager.kt +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/GoogleMobileAdsConsentManager.kt @@ -18,7 +18,7 @@ package com.google.android.gms.example.jetpackcomposedemo import android.app.Activity import android.content.Context -import com.google.android.gms.example.jetpackcomposedemo.MainViewModel.Companion.TEST_DEVICE_HASHED_ID +import com.google.android.gms.example.jetpackcomposedemo.main.MainViewModel.Companion.TEST_DEVICE_HASHED_ID import com.google.android.ump.ConsentDebugSettings import com.google.android.ump.ConsentForm.OnConsentFormDismissedListener import com.google.android.ump.ConsentInformation diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/NavDestinations.kt b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/NavDestinations.kt deleted file mode 100644 index 2fde9574d..000000000 --- a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/NavDestinations.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.google.android.gms.example.jetpackcomposedemo - -enum class NavDestinations { - Home, - Banner, -} diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/BannerScreen.kt b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/formats/BannerScreen.kt similarity index 94% rename from kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/BannerScreen.kt rename to kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/formats/BannerScreen.kt index 1945afa74..415670238 100644 --- a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/BannerScreen.kt +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/formats/BannerScreen.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.android.gms.example.jetpackcomposedemo +package com.google.android.gms.example.jetpackcomposedemo.formats import android.content.Context import android.util.Log @@ -44,7 +44,7 @@ import com.google.android.gms.ads.AdSize import com.google.android.gms.ads.AdView import com.google.android.gms.ads.LoadAdError import com.google.android.gms.compose_util.BannerAd -import com.google.android.gms.example.jetpackcomposedemo.GoogleMobileAdsApplication.Companion.BANNER_ADUNIT_ID +import com.google.android.gms.example.jetpackcomposedemo.GoogleMobileAdsApplication.Companion.BANNER_AD_UNIT_ID import com.google.android.gms.example.jetpackcomposedemo.GoogleMobileAdsApplication.Companion.TAG import com.google.android.gms.example.jetpackcomposedemo.ui.theme.JetpackComposeDemoTheme @@ -81,7 +81,7 @@ private fun loadAdaptiveBannerAd(context: Context, width: Int, isPreviewMode: Bo return adView } - adView.adUnitId = BANNER_ADUNIT_ID + adView.adUnitId = BANNER_AD_UNIT_ID val adSize = AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(context, width) adView.setAdSize(adSize) @@ -92,7 +92,7 @@ private fun loadAdaptiveBannerAd(context: Context, width: Int, isPreviewMode: Bo } override fun onAdFailedToLoad(error: LoadAdError) { - Log.e(TAG, "Banner ad failed to load.") + Log.e(TAG, "Banner ad failed to load: ${error.message}") } override fun onAdImpression() { diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/formats/LazyBannerScreen.kt b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/formats/LazyBannerScreen.kt new file mode 100644 index 000000000..82eafbc9c --- /dev/null +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/formats/LazyBannerScreen.kt @@ -0,0 +1,190 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.android.gms.example.jetpackcomposedemo.formats + +import android.content.Context +import android.util.Log +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.example.jetpackcomposedemo.R +import com.google.android.gms.ads.AdListener +import com.google.android.gms.ads.AdRequest +import com.google.android.gms.ads.AdSize +import com.google.android.gms.ads.AdView +import com.google.android.gms.ads.LoadAdError +import com.google.android.gms.compose_util.BannerAd +import com.google.android.gms.example.jetpackcomposedemo.GoogleMobileAdsApplication.Companion.BANNER_AD_UNIT_ID +import com.google.android.gms.example.jetpackcomposedemo.GoogleMobileAdsApplication.Companion.TAG +import com.google.android.gms.example.jetpackcomposedemo.ui.theme.JetpackComposeDemoTheme +import kotlin.coroutines.resume +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.supervisorScope +import kotlinx.coroutines.suspendCancellableCoroutine + +@Composable +fun LazyBannerScreen(modifier: Modifier = Modifier) { + val context = LocalContext.current + val isPreviewMode = LocalInspectionMode.current + val deviceCurrentWidth = LocalConfiguration.current.screenWidthDp + val adsToLoad = 5 + + // State for loading and completed. + var isLoading by remember { mutableStateOf(true) } + var loadedAds by remember { mutableStateOf>(emptyList()) } + val fillerText = loadFillerText(context) + + // Load ads when on launch of the composition. + LaunchedEffect(Unit) { + if (!isPreviewMode) { + loadedAds = loadBannerAds(context, adsToLoad, deviceCurrentWidth) + } + isLoading = false + } + + // Display a loading indicator if ads are still being fetched. + if (isLoading) { + CircularProgressIndicator(modifier = modifier.width(100.dp).height(100.dp)) + } else { + // Display a Lazy list of loaded ads. + LazyColumn(verticalArrangement = Arrangement.spacedBy(8.dp)) { + items(loadedAds) { adView -> + Column { + BannerAd(adView, modifier.fillMaxWidth()) + // Display the filler content. + fillerText.forEach { content -> + Box( + modifier + .fillMaxWidth() + .background(MaterialTheme.colorScheme.primaryContainer) + .padding(8.dp) + ) { + Text( + text = content, + modifier.padding(8.dp), + style = MaterialTheme.typography.bodyMedium, + ) + } + } + } + } + } + } + + // Clean up the AdViews after use. + DisposableEffect(Unit) { onDispose { loadedAds.forEach { adView -> adView.destroy() } } } +} + +@Preview +@Composable +private fun LazyBannerScreenPreview() { + JetpackComposeDemoTheme { + Surface(color = MaterialTheme.colorScheme.background) { LazyBannerScreen() } + } +} + +/** The result of attempting to load an [AdView] from `suspend. */ +sealed interface LoadAdResult { + + /** Result for when an [AdView] successfully loads. */ + class Success(val ad: AdView) : LoadAdResult + + /** Result for when an `AdView` fails to load. */ + class Failure(val error: LoadAdError) : LoadAdResult +} + +private suspend fun loadBannerAd(context: Context, width: Int): LoadAdResult { + return suspendCancellableCoroutine { continuation -> + val adView = AdView(context) + adView.adUnitId = BANNER_AD_UNIT_ID + val adSize = AdSize.getCurrentOrientationInlineAdaptiveBannerAdSize(context, width) + adView.setAdSize(adSize) + adView.adListener = + object : AdListener() { + override fun onAdLoaded() { + Log.d(TAG, "Banner ad was loaded.") + continuation.resume(LoadAdResult.Success(adView)) + } + + override fun onAdFailedToLoad(error: LoadAdError) { + Log.e(TAG, "Banner ad failed to load: ${error.message}") + adView.destroy() + continuation.resume(LoadAdResult.Failure(error)) + } + + override fun onAdImpression() { + Log.d(TAG, "Banner ad had an impression.") + } + + override fun onAdClicked() { + Log.d(TAG, "Banner ad was clicked.") + } + } + + continuation.invokeOnCancellation { + // When the coroutine is cancelled, clean up resources. + adView.destroy() + } + + val adRequest = AdRequest.Builder().build() + adView.loadAd(adRequest) + } +} + +private suspend fun loadBannerAds(context: Context, count: Int, width: Int): List = + supervisorScope { + List(count) { + async { + when (val result = loadBannerAd(context, width)) { + is LoadAdResult.Failure -> null + is LoadAdResult.Success -> result.ad + } + } + } + .awaitAll() + .filterNotNull() + } + +fun loadFillerText(context: Context): List { + val tipsArray = context.resources.getStringArray(R.array.lorem_ipsum) + return tipsArray.toList() +} diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/HomeScreen.kt b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/HomeScreen.kt similarity index 77% rename from kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/HomeScreen.kt rename to kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/HomeScreen.kt index 38805ae0a..51709ebb6 100644 --- a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/HomeScreen.kt +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/HomeScreen.kt @@ -1,4 +1,4 @@ -package com.google.android.gms.example.jetpackcomposedemo +package com.google.android.gms.example.jetpackcomposedemo.main import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth @@ -25,10 +25,17 @@ fun HomeScreen( Button( onClick = { navController.navigate(NavDestinations.Banner.name) }, enabled = uiState.canRequestAds, - modifier = modifier.fillMaxWidth(), + modifier = Modifier.fillMaxWidth(), ) { Text(LocalContext.current.getString(R.string.nav_banner)) } + Button( + onClick = { navController.navigate(NavDestinations.LazyBanner.name) }, + enabled = uiState.canRequestAds, + modifier = Modifier.fillMaxWidth(), + ) { + Text(LocalContext.current.getString(R.string.nav_lazy_banner)) + } } } diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/MainActivity.kt b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/MainActivity.kt similarity index 91% rename from kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/MainActivity.kt rename to kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/MainActivity.kt index cd2d4ac00..b6322f316 100644 --- a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/MainActivity.kt +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/MainActivity.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.android.gms.example.jetpackcomposedemo +package com.google.android.gms.example.jetpackcomposedemo.main import android.os.Bundle import android.util.Log @@ -23,6 +23,7 @@ import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.lifecycle.lifecycleScope import com.google.android.gms.ads.MobileAds +import com.google.android.gms.example.jetpackcomposedemo.GoogleMobileAdsApplication import kotlinx.coroutines.launch class MainActivity : ComponentActivity() { diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/MainScreen.kt b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/MainScreen.kt similarity index 91% rename from kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/MainScreen.kt rename to kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/MainScreen.kt index 1dbf64182..c4cd3be4f 100644 --- a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/MainScreen.kt +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/MainScreen.kt @@ -1,9 +1,8 @@ -package com.google.android.gms.example.jetpackcomposedemo +package com.google.android.gms.example.jetpackcomposedemo.main import android.content.Context import android.content.ContextWrapper import androidx.activity.ComponentActivity -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets @@ -40,6 +39,8 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.example.jetpackcomposedemo.R +import com.google.android.gms.example.jetpackcomposedemo.formats.BannerScreen +import com.google.android.gms.example.jetpackcomposedemo.formats.LazyBannerScreen import com.google.android.gms.example.jetpackcomposedemo.ui.theme.JetpackComposeDemoTheme @Composable @@ -79,6 +80,7 @@ fun MainScreen(googleMobileAdsViewModel: MainViewModel, modifier: Modifier = Mod NavHost(navController = navController, startDestination = NavDestinations.Home.name) { composable(NavDestinations.Home.name) { HomeScreen(uiState, navController) } composable(NavDestinations.Banner.name) { BannerScreen() } + composable(NavDestinations.LazyBanner.name) { LazyBannerScreen() } } Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) } @@ -120,12 +122,18 @@ private fun MainTopBar( DropdownMenuItem( text = { Text(context.getString(R.string.adinspector_open_button)) }, enabled = isMobileAdsInitialized, - onClick = onOpenAdInspector, + onClick = { + menuExpanded = false + onOpenAdInspector() + }, ) if (isPrivacyOptionsRequired) { DropdownMenuItem( text = { Text(context.getString(R.string.privacy_options_open_button)) }, - onClick = onShowPrivacyOptionsForm, + onClick = { + menuExpanded = false + onShowPrivacyOptionsForm() + }, ) } } diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/MainUiState.kt b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/MainUiState.kt similarity index 87% rename from kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/MainUiState.kt rename to kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/MainUiState.kt index 3ab98b2dd..40fb49072 100644 --- a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/MainUiState.kt +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/MainUiState.kt @@ -1,4 +1,4 @@ -package com.google.android.gms.example.jetpackcomposedemo +package com.google.android.gms.example.jetpackcomposedemo.main /** UiState for the MainViewModel. */ data class MainUiState( diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/MainViewModel.kt b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/MainViewModel.kt similarity index 95% rename from kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/MainViewModel.kt rename to kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/MainViewModel.kt index 951141166..e3790c8d1 100644 --- a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/MainViewModel.kt +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/MainViewModel.kt @@ -1,4 +1,4 @@ -package com.google.android.gms.example.jetpackcomposedemo +package com.google.android.gms.example.jetpackcomposedemo.main import android.app.Activity import android.content.Context @@ -7,6 +7,8 @@ import android.widget.Toast import com.google.android.gms.ads.MobileAds import com.google.android.gms.ads.OnAdInspectorClosedListener import com.google.android.gms.ads.RequestConfiguration +import com.google.android.gms.example.jetpackcomposedemo.GoogleMobileAdsApplication +import com.google.android.gms.example.jetpackcomposedemo.GoogleMobileAdsConsentManager import com.google.android.ump.ConsentForm import java.util.concurrent.atomic.AtomicBoolean import kotlinx.coroutines.Dispatchers diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/NavDestinations.kt b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/NavDestinations.kt new file mode 100644 index 000000000..e395a1fae --- /dev/null +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/main/NavDestinations.kt @@ -0,0 +1,7 @@ +package com.google.android.gms.example.jetpackcomposedemo.main + +enum class NavDestinations { + Home, + Banner, + LazyBanner, +} diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/ui/theme/Color.kt b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/ui/theme/Color.kt index cd67390b2..a9f515bc9 100644 --- a/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/ui/theme/Color.kt +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/java/com/google/android/gms/example/jetpackcomposedemo/ui/theme/Color.kt @@ -26,6 +26,4 @@ val Purple40 = Color(0xFF6650a4) val PurpleGrey40 = Color(0xFF625b71) val Pink40 = Color(0xFF7D5260) -val ColorStateLoaded = Color(0xFF009900) -val ColorStateUnloaded = Color(0xFFcc6600) -val ColorStateError = Color(0xFFcc0000) +val LightBlue = Color(0xFFADD8E6) diff --git a/kotlin/advanced/JetpackComposeDemo/app/src/main/res/values/strings.xml b/kotlin/advanced/JetpackComposeDemo/app/src/main/res/values/strings.xml index f0edbfc3c..c1e4b884b 100644 --- a/kotlin/advanced/JetpackComposeDemo/app/src/main/res/values/strings.xml +++ b/kotlin/advanced/JetpackComposeDemo/app/src/main/res/values/strings.xml @@ -4,6 +4,18 @@ Jetpack Compose Demo Home Banner + Lazy Banner Show Privacy Options Form Reload Ad + + Semper adhibitiones probationales in evolutione adhibe. + Utere vexillis adaptivis in linea pro praeconiis intra materiam pascendi. + Utere vexillis adaptivis pro magnitudinibus praeconiorum per machinas optimizatis. + Imple consensum ad recipienda praeconia personalizata in EEA permittenda. + Permitte fontes praeconiorum licitantes ad vectigal praeconiorum emendandum. + Voca MobileAds.initialize() in filo secundario ad ANRs vitandos. + Loca praeconiorum diligenter in variis machinis et magnitudinibus tegumentorum proba. + Utere Inspectore Praeconiorum ad inquisitiones et responsa praeconiorum corrigenda. + Habes responsum in hoc exemplo? Fac nos scire in Github! +