跳转到主要内容

Documentation Index

Fetch the complete documentation index at: https://docs.cloudx.io/llms.txt

Use this file to discover all available pages before exploring further.

即将推出 — 原生广告尚未开放通用访问。本节仅面向早期集成合作伙伴发布。原生广告 API 在正式发布前可能会有变更。
原生广告允许您使用自定义 UI 组件(标题、正文、图标、媒体、行动号召)按自己的布局渲染广告素材。配合视频素材和正确的播放设置,原生广告即可成为全屏垂直 “Reels”(与 Instagram Reels 或 TikTok 相同的用户体验)。 一个 Reel 由三部分构成:
  1. 包含视频内容的原生广告。 广告的 mediaView 包含视频播放器,其他素材(标题、正文、图标、CTA)覆盖在视频上方。
  2. 视频播放设置。 加载器上的三个属性可以禁用全屏、开启有声播放以及隐藏媒体控件。
  3. 全屏分页容器。 垂直方向的 ViewPager2,每一页即为一个 Reel。

Reels API 接口

功能CloudX API描述
检测视频素材ad.nativeAd?.isVideoContent当加载的素材是视频时返回 true
获取视频时长ad.nativeAd?.videoDuration视频时长(秒),未知时为 0.0
用户关闭广告onNativeAdClosed(ad) 监听回调当用户通过 AdChoices 举报或隐藏广告时触发
禁用全屏loader.isVideoFullScreenDisabled = true阻止视频在点击时进入全屏
开启有声播放loader.isStartVideoUnmuted = true以有声状态开始播放
隐藏媒体控件loader.isVideoMediaControlsHidden = true隐藏播放/暂停和进度条控件
原生广告适配器支持情况和依赖要求记录在各适配器概览页中。当前原生广告支持请参阅 Meta Audience Network 适配器

创建布局和视图绑定器

res/layout/native_ad_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">

        <FrameLayout
            android:id="@+id/native_ad_options"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:gravity="center_vertical">

            <ImageView
                android:id="@+id/native_ad_icon"
                android:layout_width="48dp"
                android:layout_height="48dp" />

            <TextView
                android:id="@+id/native_ad_title"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:layout_marginStart="8dp"
                android:textSize="16sp"
                android:textStyle="bold" />
        </LinearLayout>

        <TextView
            android:id="@+id/native_ad_body"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp" />

        <FrameLayout
            android:id="@+id/native_ad_media_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:gravity="center_vertical">

            <TextView
                android:id="@+id/native_ad_advertiser"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:textColor="#888" />

            <Button
                android:id="@+id/native_ad_cta"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>

    </LinearLayout>
</FrameLayout>
val binder = CloudXNativeAdViewBinder.Builder(R.layout.native_ad_layout)
    .setTitleTextViewId(R.id.native_ad_title)
    .setBodyTextViewId(R.id.native_ad_body)
    .setIconImageViewId(R.id.native_ad_icon)
    .setMediaContentViewGroupId(R.id.native_ad_media_container)
    .setCallToActionButtonId(R.id.native_ad_cta)
    .setOptionsContentViewGroupId(R.id.native_ad_options)
    .setAdvertiserTextViewId(R.id.native_ad_advertiser)
    .build()

创建加载器并配置视频

class YourActivity : AppCompatActivity(), CloudXNativeAdListener, CloudXAdRevenueListener {
    private lateinit var nativeAdLoader: CloudXNativeAdLoader

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        nativeAdLoader = CloudX.createNativeAdLoader(this, "your-native-ad-unit-id")
        nativeAdLoader.nativeAdListener = this
        nativeAdLoader.revenueListener = this

        nativeAdLoader.isVideoFullScreenDisabled = true
        nativeAdLoader.isStartVideoUnmuted = true
        nativeAdLoader.isVideoMediaControlsHidden = true
    }

    override fun onDestroy() {
        super.onDestroy()
        nativeAdLoader.destroy()
    }
}
属性默认值Reels 值描述
isVideoFullScreenDisabledfalsetrue阻止视频在点击时进入全屏
isStartVideoUnmutedfalsetrue以有声状态开始视频播放
isVideoMediaControlsHiddenfalsetrue隐藏播放/暂停和进度条控件
在调用 loadAd() 之前设置以上属性。对静态图片素材无效。对于 Reels 风格的信息流,将三个属性都设为 true

加载广告

流程 A — 加载到预构建的视图中:
val adView = CloudXNativeAdView(this, binder)
nativeAdLoader.loadAd(adView)
流程 B — 先加载,后渲染(延迟渲染):
nativeAdLoader.loadAd()

override fun onNativeAdLoaded(adView: CloudXNativeAdView?, ad: CloudXAd) {
    val newAdView = CloudXNativeAdView(this@YourActivity, binder)
    nativeAdLoader.render(newAdView, ad)
    container.addView(newAdView)
}

处理回调

// 必选回调

override fun onNativeAdLoaded(adView: CloudXNativeAdView?, ad: CloudXAd) {
    Log.d("CloudX", "Native ad loaded from ${ad.networkName}")

    ad.nativeAd?.let { nativeAd ->
        if (nativeAd.isVideoContent) {
            Log.d("CloudX", "Video duration: ${nativeAd.videoDuration}s")
        }
    }

    adView?.let { container.addView(it) }
}

override fun onNativeAdLoadFailed(adUnitId: String, error: CloudXError) {
    Log.e("CloudX", "Native ad failed to load: ${error.message}")
}

override fun onNativeAdClicked(ad: CloudXAd) {
    Log.d("CloudX", "Native ad clicked")
}

// 可选回调(默认空实现)

override fun onNativeAdExpired(ad: CloudXAd) {
    Log.d("CloudX", "Native ad expired — destroy and reload")
    nativeAdLoader.destroy(ad)
    nativeAdLoader.loadAd()
}

override fun onNativeAdClosed(ad: CloudXAd) {
    Log.d("CloudX", "User dismissed the ad via AdChoices")
    nativeAdLoader.destroy(ad)
}

// 收入回调

override fun onAdRevenuePaid(cloudXAd: CloudXAd) {
    Log.d("CloudX", "Native ad revenue: ${cloudXAd.revenue} from ${cloudXAd.networkName}")
}

清理资源

使用完毕后务必销毁广告:
// 销毁特定已加载的广告
nativeAdLoader.destroy(ad)

// 销毁加载器及所有关联资源
nativeAdLoader.destroy()

原生广告素材(CloudXNativeAd)

CloudXNativeAd 接口可通过监听回调中的 ad.nativeAd 获取:
属性类型描述
titleString?标题文本
bodyString?正文/描述文本
callToActionString?CTA 按钮文本(例如 “Install Now”)
advertiserString?广告主名称
iconCloudXNativeAdImage?应用图标(DrawableUri
mainImageCloudXNativeAdImage?主图片(静态素材)
mediaViewView?视频/媒体播放器视图(适配器提供)
optionsViewView?AdChoices 或选项视图(适配器提供)
mediaContentAspectRatioFloat媒体内容的宽高比
starRatingDouble?应用商店评分(0–5)
isVideoContentBoolean素材是否为视频
videoDurationDouble视频时长(秒),未知时为 0.0
isExpiredBoolean广告是否已过期

Reels 信息流提示

  • 使用 ViewPager2 并设置 android:orientation="vertical",每个条目宽高都为 MATCH_PARENT
  • 回收条目时对 CloudXNativeAdView 调用 prepareForReuse()
  • 每个广告位创建一个 CloudXNativeAdLoader,按顺序加载广告。
  • 当广告不再需要时,通过 destroy(ad) 销毁。