Skip to content

Commit 0844aca

Browse files
nventimiglicopybara-github
authored andcommitted
Added display Native Ad code snippets.
PiperOrigin-RevId: 789811557
1 parent 0a4f6f7 commit 0844aca

File tree

4 files changed

+274
-3
lines changed

4 files changed

+274
-3
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<com.google.android.gms.ads.nativead.NativeAdView
2+
xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:layout_width="match_parent"
4+
android:layout_height="wrap_content">
5+
<LinearLayout
6+
android:orientation="vertical">
7+
<LinearLayout
8+
android:orientation="horizontal">
9+
<ImageView
10+
android:id="@+id/ad_app_icon" />
11+
<TextView
12+
android:id="@+id/ad_headline" />
13+
</LinearLayout>
14+
<!--Add remaining assets such as the image and media view.-->
15+
</LinearLayout>
16+
</com.google.android.gms.ads.nativead.NativeAdView>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<com.google.android.gms.ads.nativead.NativeAdView
2+
xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:layout_width="match_parent"
4+
android:layout_height="wrap_content">
5+
<LinearLayout
6+
android:orientation="vertical">
7+
<LinearLayout
8+
android:orientation="horizontal">
9+
<ImageView
10+
android:id="@+id/ad_app_icon" />
11+
<TextView
12+
android:id="@+id/ad_headline" />
13+
</LinearLayout>
14+
<!--Add remaining assets such as the image and media view.-->
15+
</LinearLayout>
16+
</com.google.android.gms.ads.nativead.NativeAdView>

kotlin/advanced/APIDemo/app/src/main/java/com/google/android/gms/snippets/NativeAdSnippets.kt

Lines changed: 104 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,18 @@
1414

1515
package com.google.android.gms.snippets
1616

17+
import android.app.Activity
1718
import android.content.Context
19+
import android.view.LayoutInflater
20+
import android.view.View
21+
import android.widget.FrameLayout
1822
import com.google.android.gms.ads.AdListener
1923
import com.google.android.gms.ads.AdLoader
2024
import com.google.android.gms.ads.AdRequest
2125
import com.google.android.gms.ads.LoadAdError
2226
import com.google.android.gms.ads.admanager.AdManagerAdRequest
2327
import com.google.android.gms.ads.nativead.NativeAd
2428
import com.google.android.gms.ads.nativead.NativeAdOptions
25-
import kotlinx.coroutines.CoroutineScope
26-
import kotlinx.coroutines.Dispatchers
27-
import kotlinx.coroutines.launch
2829

2930
/** Kotlin code snippets for the developer guide. */
3031
internal class NativeAdSnippets {
@@ -97,6 +98,106 @@ internal class NativeAdSnippets {
9798
// [END handle_ad_loaded]
9899
}
99100

101+
private fun handleAdLoadedWithDisplay(
102+
adLoaderBuilder: AdLoader.Builder,
103+
activity: Activity,
104+
layoutInflater: LayoutInflater,
105+
layoutPlaceholder: FrameLayout,
106+
) {
107+
// [START handle_ad_loaded_with_display]
108+
adLoaderBuilder
109+
.forNativeAd { nativeAd ->
110+
// This callback is invoked when a native ad is successfully loaded.
111+
activity.runOnUiThread {
112+
val nativeAdBinding = NativeAdBinding.inflate(layoutInflater)
113+
val adView = nativeAdBinding.root
114+
115+
// Populate and register the native ad asset views.
116+
displayNativeAdView(nativeAd, nativeAdBinding)
117+
118+
// Remove all old ad views and add the new native ad
119+
// view to the view hierarchy.
120+
layoutPlaceholder.removeAllViews()
121+
layoutPlaceholder.addView(adView)
122+
}
123+
}
124+
.build()
125+
// [END handle_ad_loaded_with_display]
126+
}
127+
128+
private fun displayNativeAdView(nativeAd: NativeAd, nativeAdBinding: NativeAdBinding) {
129+
// [START display_native_ad]
130+
val nativeAdView = nativeAdBinding.root
131+
132+
// Set the media view.
133+
nativeAdView.mediaView = nativeAdBinding.adMedia
134+
135+
// Set other ad assets.
136+
nativeAdView.headlineView = nativeAdBinding.adHeadline
137+
nativeAdView.bodyView = nativeAdBinding.adBody
138+
nativeAdView.callToActionView = nativeAdBinding.adCallToAction
139+
nativeAdView.iconView = nativeAdBinding.adAppIcon
140+
nativeAdView.priceView = nativeAdBinding.adPrice
141+
nativeAdView.starRatingView = nativeAdBinding.adStars
142+
nativeAdView.storeView = nativeAdBinding.adStore
143+
nativeAdView.advertiserView = nativeAdBinding.adAdvertiser
144+
145+
nativeAdBinding.adHeadline.text = nativeAd.headline
146+
nativeAd.mediaContent?.let { nativeAdBinding.adMedia.setMediaContent(it) }
147+
148+
if (nativeAd.body == null) {
149+
nativeAdBinding.adBody.visibility = View.INVISIBLE
150+
} else {
151+
nativeAdBinding.adBody.text = nativeAd.body
152+
nativeAdBinding.adBody.visibility = View.VISIBLE
153+
}
154+
155+
if (nativeAd.callToAction == null) {
156+
nativeAdBinding.adCallToAction.visibility = View.INVISIBLE
157+
} else {
158+
nativeAdBinding.adCallToAction.text = nativeAd.callToAction
159+
nativeAdBinding.adCallToAction.visibility = View.VISIBLE
160+
}
161+
162+
if (nativeAd.icon == null) {
163+
nativeAdBinding.adAppIcon.visibility = View.GONE
164+
} else {
165+
nativeAdBinding.adAppIcon.setImageDrawable(nativeAd.icon?.drawable)
166+
nativeAdBinding.adAppIcon.visibility = View.VISIBLE
167+
}
168+
169+
if (nativeAd.price == null) {
170+
nativeAdBinding.adPrice.visibility = View.INVISIBLE
171+
} else {
172+
nativeAdBinding.adPrice.text = nativeAd.price
173+
nativeAdBinding.adPrice.visibility = View.VISIBLE
174+
}
175+
176+
if (nativeAd.store == null) {
177+
nativeAdBinding.adStore.visibility = View.INVISIBLE
178+
} else {
179+
nativeAdBinding.adStore.text = nativeAd.store
180+
nativeAdBinding.adStore.visibility = View.VISIBLE
181+
}
182+
183+
if (nativeAd.starRating == null) {
184+
nativeAdBinding.adStars.visibility = View.INVISIBLE
185+
} else {
186+
nativeAdBinding.adStars.rating = nativeAd.starRating!!.toFloat()
187+
nativeAdBinding.adStars.visibility = View.VISIBLE
188+
}
189+
190+
if (nativeAd.advertiser == null) {
191+
nativeAdBinding.adAdvertiser.visibility = View.INVISIBLE
192+
} else {
193+
nativeAdBinding.adAdvertiser.text = nativeAd.advertiser
194+
nativeAdBinding.adAdvertiser.visibility = View.VISIBLE
195+
}
196+
197+
nativeAdView.setNativeAd(nativeAd)
198+
// [END display_native_ad]
199+
}
200+
100201
private fun destroyAd(nativeAd: NativeAd) {
101202
// [START destroy_ad]
102203
nativeAd.destroy()
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// Copyright 2025 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.android.gms.example.jetpackcomposedemo.snippets
16+
17+
import androidx.compose.foundation.layout.Box
18+
import androidx.compose.foundation.layout.Column
19+
import androidx.compose.foundation.layout.fillMaxHeight
20+
import androidx.compose.foundation.layout.fillMaxWidth
21+
import androidx.compose.foundation.layout.height
22+
import androidx.compose.foundation.layout.padding
23+
import androidx.compose.foundation.layout.wrapContentHeight
24+
import androidx.compose.material3.MaterialTheme
25+
import androidx.compose.material3.Text
26+
import androidx.compose.runtime.Composable
27+
import androidx.compose.ui.Alignment
28+
import androidx.compose.ui.Modifier
29+
import androidx.compose.ui.platform.LocalContext
30+
import androidx.compose.ui.unit.dp
31+
import com.example.jetpackcomposedemo.R
32+
import com.google.android.gms.ads.nativead.NativeAd
33+
import com.google.android.gms.compose_util.NativeAdAttribution
34+
import com.google.android.gms.compose_util.NativeAdHeadlineView
35+
import com.google.android.gms.compose_util.NativeAdMediaView
36+
import com.google.android.gms.compose_util.NativeAdView
37+
38+
/** Kotlin code snippets for the developer guide. */
39+
internal class NativeAdSnippets {
40+
41+
// [START define_native_ad_view]
42+
@Composable
43+
/** Display a native ad with a user defined template. */
44+
fun DisplayNativeAdView(nativeAd: NativeAd) {
45+
val context = LocalContext.current
46+
Box(modifier = Modifier.padding(8.dp).wrapContentHeight(Alignment.Top)) {
47+
// Call the NativeAdView composable to display the native ad.
48+
NativeAdView {
49+
// Inside the NativeAdView composable, display the native ad assets.
50+
Column(Modifier.align(Alignment.TopStart).wrapContentHeight(Alignment.Top)) {
51+
// Display the ad attribution. This is required.
52+
NativeAdAttribution(text = context.getString(R.string.attribution))
53+
// Display the headline asset. This is required.
54+
nativeAd.headline?.let {
55+
NativeAdHeadlineView { Text(text = it, style = MaterialTheme.typography.headlineLarge) }
56+
}
57+
// Display the media asset. This is required.
58+
NativeAdMediaView(Modifier.fillMaxWidth().height(500.dp).fillMaxHeight())
59+
}
60+
}
61+
}
62+
}
63+
64+
// [END define_native_ad_view]
65+
66+
// [START load_native_ad_for_display]
67+
@Composable
68+
fun loadAndDisplayNativeAd() {
69+
var nativeAd by remember { mutableStateOf<NativeAd?>(null) }
70+
val context = LocalContext.current
71+
var isDisposed by remember { mutableStateOf(false) }
72+
73+
DisposableEffect(Unit) {
74+
// Load the native ad when we launch this screen
75+
loadNativeAd(
76+
context = context,
77+
onAdLoaded = { ad ->
78+
// Handle the native ad being loaded.
79+
if (!isDisposed) {
80+
nativeAd = ad
81+
} else {
82+
// Destroy the native ad if loaded after the screen is disposed.
83+
ad.destroy()
84+
}
85+
},
86+
)
87+
// Destroy the native ad to prevent memory leaks when we dispose of this screen.
88+
onDispose {
89+
isDisposed = true
90+
nativeAd?.destroy()
91+
nativeAd = null
92+
}
93+
}
94+
95+
// Display the native ad view with a user defined template.
96+
nativeAd?.let { adValue -> displayNativeAdView(adValue) }
97+
}
98+
99+
fun loadNativeAd(context: Context, onAdLoaded: (NativeAd) -> Unit) {
100+
val adLoader =
101+
AdLoader.Builder(context, NATIVE_AD_UNIT_ID)
102+
.forNativeAd { nativeAd -> onAdLoaded(nativeAd) }
103+
.withAdListener(
104+
object : AdListener() {
105+
override fun onAdFailedToLoad(error: LoadAdError) {
106+
Log.e(TAG, "Native ad failed to load: ${error.message}")
107+
}
108+
109+
override fun onAdLoaded() {
110+
Log.d(TAG, "Native ad was loaded.")
111+
}
112+
113+
override fun onAdImpression() {
114+
Log.d(TAG, "Native ad recorded an impression.")
115+
}
116+
117+
override fun onAdClicked() {
118+
Log.d(TAG, "Native ad was clicked.")
119+
}
120+
}
121+
)
122+
.build()
123+
adLoader.loadAd(AdRequest.Builder().build())
124+
}
125+
126+
// [END load_native_ad_for_display]
127+
128+
private companion object {
129+
// Test ad unit IDs.
130+
// For more information,
131+
// see https://developers.google.com/admob/android/test-ads.
132+
// and https://developers.google.com/ad-manager/mobile-ads-sdk/android/test-ads.
133+
const val AD_UNIT_ID = "ca-app-pub-3940256099942544/2247696110"
134+
const val VIDEO_AD_UNIT_ID = "ca-app-pub-3940256099942544/1044960115"
135+
const val ADMANAGER_AD_UNIT_ID = "/21775744923/example/native"
136+
const val ADMANAGER_VIDEO_AD_UNIT_ID = "/21775744923/example/native-video"
137+
}
138+
}

0 commit comments

Comments
 (0)