顯示 NativeAd
載入原生廣告時,Google Mobile Ads SDK 會叫用相應廣告格式的事件監聽器,然後由應用程式顯示廣告 (不必立即顯示)。SDK 提供一些實用資源,方便顯示系統定義的廣告格式,詳見下文。
定義 NativeAdView
類別
定義 NativeAdView
類別。這是 ViewGroup
類別,也是 NativeAdView
類別的頂層容器。每個原生廣告檢視區塊都包含原生廣告素材資源 (例如 MediaView
或 Title
檢視區塊元素),這類素材資源須為 NativeAdView
物件的子項。
XML 版面配置
在專案中新增 XML NativeAdView
:
<com.google.android.gms.ads.nativead.NativeAdView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical">
<LinearLayout
android:orientation="horizontal">
<ImageView
android:id="@+id/ad_app_icon" />
<TextView
android:id="@+id/ad_headline" />
</LinearLayout>
<!--Add remaining assets such as the image and media view.-->
</LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
Jetpack Compose
加入 JetpackComposeDemo/compose-util 模組,其中包含用於撰寫 NativeAdView
及素材資源的輔助程式。
使用 compose-util
模組撰寫 NativeAdView
:
import com.google.android.gms.compose_util.NativeAdAttribution
import com.google.android.gms.compose_util.NativeAdView
@Composable
/** Display a native ad with a user defined template. */
fun DisplayNativeAdView(nativeAd: NativeAd) {
NativeAdView {
// Display the ad attribution.
NativeAdAttribution(text = context.getString("Ad"))
// Add remaining assets such as the image and media view.
}
}
處理已載入的原生廣告
載入原生廣告時,請處理回呼事件、加載原生廣告檢視區塊,並加到檢視區塊階層:
Java
AdLoader.Builder builder = new AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110")
.forNativeAd(new NativeAd.OnNativeAdLoadedListener() {
@Override
public void onNativeAdLoaded(NativeAd nativeAd) {
// Assumes you have a placeholder FrameLayout in your View layout
// (with ID fl_adplaceholder) where the ad is to be placed.
FrameLayout frameLayout =
findViewById(R.id.fl_adplaceholder);
// Assumes that your ad layout is in a file call native_ad_layout.xml
// in the res/layout folder
NativeAdView adView = (NativeAdView) getLayoutInflater()
.inflate(R.layout.native_ad_layout, null);
// This method sets the assets into the ad view.
populateNativeAdView(nativeAd, adView);
frameLayout.removeAllViews();
frameLayout.addView(adView);
}
});
Kotlin
val builder = AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110")
.forNativeAd { nativeAd ->
// Assumes you have a placeholder FrameLayout in your View layout
// (with ID fl_adplaceholder) where the ad is to be placed.
val frameLayout: FrameLayout = findViewById(R.id.fl_adplaceholder)
// Assumes that your ad layout is in a file call native_ad_layout.xml
// in the res/layout folder
val adView = layoutInflater
.inflate(R.layout.native_ad_layout, null) as NativeAdView
// This method sets the assets into the ad view.
populateNativeAdView(nativeAd, adView)
frameLayout.removeAllViews()
frameLayout.addView(adView)
}
Jetpack Compose
@Composable
/** Load and display a native ad. */
fun NativeScreen() {
var nativeAd by remember { mutableStateOf<NativeAd?>(null) }
val context = LocalContext.current
var isDisposed by remember { mutableStateOf(false) }
DisposableEffect(Unit) {
// Load the native ad when we launch this screen
loadNativeAd(
context = context,
onAdLoaded = { ad ->
// Handle the native ad being loaded.
if (!isDisposed) {
nativeAd = ad
} else {
// Destroy the native ad if loaded after the screen is disposed.
ad.destroy()
}
},
)
// Destroy the native ad to prevent memory leaks when we dispose of this screen.
onDispose {
isDisposed = true
nativeAd?.destroy()
nativeAd = null
}
}
// Display the native ad view with a user defined template.
nativeAd?.let { adValue -> DisplayNativeAdView(adValue) }
}
fun loadNativeAd(context: Context, onAdLoaded: (NativeAd) -> Unit) {
val adLoader =
AdLoader.Builder(context, NATIVE_AD_UNIT_ID)
.forNativeAd { nativeAd -> onAdLoaded(nativeAd) }
.withAdListener(
object : AdListener() {
override fun onAdFailedToLoad(error: LoadAdError) {
Log.e(TAG, "Native ad failed to load: ${error.message}")
}
override fun onAdLoaded() {
Log.d(TAG, "Native ad was loaded.")
}
override fun onAdImpression() {
Log.d(TAG, "Native ad recorded an impression.")
}
override fun onAdClicked() {
Log.d(TAG, "Native ad was clicked.")
}
}
)
.build()
adLoader.loadAd(AdRequest.Builder().build())
}
請注意,特定原生廣告的所有素材資源,都應在 NativeAdView
版面配置內顯示。如果原生素材資源顯示在原生廣告檢視區塊版面配置之外,Google Mobile Ads SDK 會嘗試記錄警告。
廣告檢視區塊類別提供多種方法,可註冊個別素材資源使用的檢視區塊,還有一個方法可註冊 NativeAd
物件。以這種方式註冊檢視區塊,SDK 就能自動處理下列工作:
- 記錄點擊
- 記錄曝光 (畫面顯示第一個像素時)
- 顯示 AdChoices 疊加層
AdChoices 疊加層
SDK 會在每個廣告檢視區塊加入 AdChoices 疊加層。在原生廣告檢視區塊保留偏好的角落,供系統自動插入 AdChoices 標誌。疊加在廣告中的 AdChoices 標籤須清楚易見,請選用合適的背景顏色和圖片。請參閱原生廣告欄位說明,進一步瞭解疊加層的外觀和功能。
廣告標示
務必顯示廣告標示,表明觀看內容為廣告。 詳情請參閱政策規範。
程式碼範例
顯示原生廣告的步驟如下:
- 建立
NativeAdView
類別的執行個體。 為確保各項廣告素材資源能順利顯示,請完成以下動作:
- 在素材資源檢視區塊中,填入廣告物件內的素材資源。
- 使用
NativeAdView
類別註冊素材資源檢視區塊。
如果原生廣告版面配置包含大型媒體素材資源,請註冊
MediaView
。使用
NativeAdView
類別註冊廣告物件。
以下是顯示 NativeAd
的函式範例:
Java
private void displayNativeAd(ViewGroup parent, NativeAd ad) {
// Inflate a layout and add it to the parent ViewGroup.
LayoutInflater inflater = (LayoutInflater) parent.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
NativeAdView adView = (NativeAdView) inflater
.inflate(R.layout.ad_layout_file, parent);
// Locate the view that will hold the headline, set its text, and call the
// NativeAdView's setHeadlineView method to register it.
TextView headlineView = adView.findViewById<TextView>(R.id.ad_headline);
headlineView.setText(ad.getHeadline());
adView.setHeadlineView(headlineView);
// Repeat the process for the other assets in the NativeAd
// using additional view objects (Buttons, ImageViews, etc).
// If the app is using a MediaView, it should be
// instantiated and passed to setMediaView. This view is a little different
// in that the asset is populated automatically, so there's one less step.
MediaView mediaView = (MediaView) adView.findViewById(R.id.ad_media);
adView.setMediaView(mediaView);
// Call the NativeAdView's setNativeAd method to register the
// NativeAdObject.
adView.setNativeAd(ad);
// Ensure that the parent view doesn't already contain an ad view.
parent.removeAllViews();
// Place the AdView into the parent.
parent.addView(adView);
}
Kotlin
fun displayNativeAd(parent: ViewGroup, ad: NativeAd) {
// Inflate a layout and add it to the parent ViewGroup.
val inflater = parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)
as LayoutInflater
val adView = inflater.inflate(R.layout.ad_layout_file, parent) as NativeAdView
// Locate the view that will hold the headline, set its text, and use the
// NativeAdView's headlineView property to register it.
val headlineView = adView.findViewById<TextView>(R.id.ad_headline)
headlineView.text = ad.headline
adView.headlineView = headlineView
// Repeat the process for the other assets in the NativeAd using
// additional view objects (Buttons, ImageViews, etc).
val mediaView = adView.findViewById<MediaView>(R.id.ad_media)
adView.mediaView = mediaView
// Call the NativeAdView's setNativeAd method to register the
// NativeAdObject.
adView.setNativeAd(ad)
// Ensure that the parent view doesn't already contain an ad view.
parent.removeAllViews()
// Place the AdView into the parent.
parent.addView(adView)
}
Jetpack Compose
@Composable
/** Display a native ad with a user defined template. */
fun DisplayNativeAdView(nativeAd: NativeAd) {
val context = LocalContext.current
Box(modifier = Modifier.padding(8.dp).wrapContentHeight(Alignment.Top)) {
// Call the NativeAdView composable to display the native ad.
NativeAdView {
// Inside the NativeAdView composable, display the native ad assets.
Column(Modifier.align(Alignment.TopStart).wrapContentHeight(Alignment.Top)) {
// Display the ad attribution.
NativeAdAttribution(text = context.getString(R.string.attribution))
Row {
// If available, display the icon asset.
nativeAd.icon?.let { icon ->
NativeAdIconView(Modifier.padding(5.dp)) {
icon.drawable?.toBitmap()?.let { bitmap ->
Image(bitmap = bitmap.asImageBitmap(), "Icon")
}
}
}
Column {
// If available, display the headline asset.
nativeAd.headline?.let {
NativeAdHeadlineView {
Text(text = it, style = MaterialTheme.typography.headlineLarge)
}
}
// If available, display the star rating asset.
nativeAd.starRating?.let {
NativeAdStarRatingView {
Text(text = "Rated $it", style = MaterialTheme.typography.labelMedium)
}
}
}
}
// If available, display the body asset.
nativeAd.body?.let { NativeAdBodyView { Text(text = it) } }
// Display the media asset.
NativeAdMediaView(Modifier.fillMaxWidth().height(500.dp).fillMaxHeight())
Row(Modifier.align(Alignment.End).padding(5.dp)) {
// If available, display the price asset.
nativeAd.price?.let {
NativeAdPriceView(Modifier.padding(5.dp).align(Alignment.CenterVertically)) {
Text(text = it)
}
}
// If available, display the store asset.
nativeAd.store?.let {
NativeAdStoreView(Modifier.padding(5.dp).align(Alignment.CenterVertically)) {
Text(text = it)
}
}
// If available, display the call to action asset.
// Note: The Jetpack Compose button implements a click handler which overrides the native
// ad click handler, causing issues. Use the NativeAdButton which does not implement a
// click handler. To handle native ad clicks, use the NativeAd AdListener onAdClicked
// callback.
nativeAd.callToAction?.let { callToAction ->
NativeAdCallToActionView(Modifier.padding(5.dp)) { NativeAdButton(text = callToAction) }
}
}
}
}
}
}
各項工作如下:
加載版面配置
Java
LayoutInflater inflater = (LayoutInflater) parent.getContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); NativeAdView adView = (NativeAdView) inflater .inflate(R.layout.ad_layout_file, parent);
Kotlin
val inflater = parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater val adView = inflater.inflate(R.layout.ad_layout_file, parent) as NativeAdView
這段程式碼會加載 XML 版面配置,當中的檢視區塊可用於顯示原生廣告,以及找出
NativeAdView
的參照。請注意,您可以重複利用片段或活動中現有的NativeAdView
,甚至可動態建立執行個體,不必使用版面配置檔案。填入並註冊素材資源檢視區塊
這段程式碼範例可找出用於顯示廣告標題的檢視區塊、使用廣告物件提供的字串素材資源設定標題文字,並註冊至
NativeAdView
物件:Java
TextView headlineView = adView.findViewById<TextView>(R.id.ad_headline); headlineView.setText(ad.getHeadline()); adView.setHeadlineView(headlineView);
Kotlin
val headlineView = adView.findViewById<TextView>(R.id.ad_headline) headlineView.text = ad.headline adView.headlineView = headlineView
對於應用程式顯示的原生廣告物件,其中每項素材資源都應完成下列程序:找出檢視區塊、設定相應值,並向廣告檢視區塊類別註冊。
處理點擊
請勿在原生廣告檢視區塊上方或內部,導入任何自訂點擊處理常式。只要正確填入素材資源檢視區塊,並按上一節指示完成註冊,SDK 就會處理廣告檢視區塊素材資源的點擊。
如要監聽點擊事件,請導入 Google Mobile Ads SDK 點擊回呼:
Java
AdLoader adLoader = new AdLoader.Builder(context, "ca-app-pub-3940256099942544/2247696110") // ... .withAdListener(new AdListener() { @Override public void onAdFailedToLoad(LoadAdError adError) { // Handle the failure by logging. } @Override public void onAdClicked() { // Log the click event or other custom behavior. } }) .build();
Kotlin
val adLoader = AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110") // ... .withAdListener(object : AdListener() { override fun onAdFailedToLoad(adError: LoadAdError) { // Handle the failure. } override fun onAdClicked() { // Log the click event or other custom behavior. } }) .build()
註冊 MediaView
如要在原生廣告的版面配置中加入主要圖片素材資源,請使用
MediaView
,而不是ImageView
。MediaView
是專門設計的View
,用於顯示主要媒體素材資源 (影片或圖片)。MediaView
可在 XML 版面配置中定義,也可以動態建構,且如同其他素材資源檢視區塊,都應加入NativeAdView
的檢視區塊階層。使用MediaView
的應用程式須向NativeAdView
註冊:Java
// Populate and register the media asset view. nativeAdView.setMediaView(nativeAdBinding.adMedia);
Kotlin
// Populate and register the media asset view. nativeAdView.mediaView = nativeAdBinding.adMedia
ImageScaleType
顯示圖片時,
MediaView
類別具備ImageScaleType
屬性。如要變更圖片在MediaView
中的縮放方式,請使用MediaView
的setImageScaleType()
方法,設定對應的ImageView.ScaleType
:Java
mediaView.setImageScaleType(ImageView.ScaleType.CENTER_CROP);
Kotlin
mediaView.imageScaleType = ImageView.ScaleType.CENTER_CROP
MediaContent
MediaContent
類別會保留與原生廣告媒體內容相關的資料,並使用MediaView
類別顯示。使用MediaContent
執行個體設定MediaView
mediaContent
屬性時,請注意以下事項:如有可用的影片素材資源,該影片會緩衝處理並開始於
MediaView
播放。您可以檢查hasVideoContent()
,判斷是否有影片素材資源。如果廣告不含影片素材資源,系統會下載
mainImage
素材資源,並加到MediaView
中。
根據預設,第一個下載的圖片素材資源是
mainImage
。如果使用setReturnUrlsForImageAssets(true)
,mainImage
的值會是null
,您需要將mainImage
屬性設為手動下載的圖片。請注意,只有在沒有可用的影片素材資源時,系統才會使用這張圖片。註冊原生廣告物件
最後一個步驟是在顯示原生廣告的檢視區塊,註冊原生廣告物件。
Java
adView.setNativeAd(ad);
Kotlin
adView.setNativeAd(ad)
刪除廣告
顯示原生廣告後,請將廣告刪除。以下示範如何刪除原生廣告:
Java
nativeAd.destroy();
Kotlin
nativeAd.destroy()
GitHub 上的範例
完整導入原生廣告的範例:
後續步驟
請參閱下列主題: