Skip to main content

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.

Coming Soon — Native ads are not yet available for general use. This section is published for early integration partners only. The native ads API is subject to change before public release.
Native ads let you render ad creatives using your own UI components — title, body, icon, media, call-to-action — in your own layout. With video creatives and the right playback settings, native ads become full-screen vertical “Reels” (the same UX as Instagram Reels or TikTok). A Reel is built from three things:
  1. A native ad with video content. The ad’s mediaView contains the video player. Other assets (title, body, icon, CTA) are overlaid on top.
  2. Video playback settings. Three properties on the loader disable fullscreen, start the video with sound, and hide media controls.
  3. A full-screen paging container. A ViewPager2 with android:orientation="vertical". Each page is one Reel.

Reels API Surface

CapabilityCloudX APIDescription
Detect video creativead.nativeAd?.isVideoContentReturns true when the loaded creative is a video
Get video durationad.nativeAd?.videoDurationDuration of the video in seconds (0.0 if unknown)
Ad dismissed by useronNativeAdClosed(ad) listener callbackFires when the user reports or hides the ad via AdChoices
Disable fullscreenloader.isVideoFullScreenDisabled = truePrevents the video from entering fullscreen on tap
Start unmutedloader.isStartVideoUnmuted = trueStarts playback with sound on
Hide media controlsloader.isVideoMediaControlsHidden = trueHides play/pause and progress bar controls
Native-ad adapter support and dependencies are documented on the adapter overview pages. See the Meta Audience Network adapter for current native-ad support.

Create a Layout and View Binder

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()

Create a Loader and Configure Video

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()
    }
}
PropertyDefaultReels ValueDescription
isVideoFullScreenDisabledfalsetruePrevents the video from entering fullscreen when tapped
isStartVideoUnmutedfalsetrueStarts video playback with sound on
isVideoMediaControlsHiddenfalsetrueHides play/pause and progress bar controls
Set these properties before calling loadAd(). They are ignored for static image creatives. For a Reels-style feed, set all three to true.

Load the Ad

Flow A — Load into a pre-built view:
val adView = CloudXNativeAdView(this, binder)
nativeAdLoader.loadAd(adView)
Flow B — Load first, render later (deferred rendering):
nativeAdLoader.loadAd()

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

Handle Callbacks

// Required callbacks

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")
}

// Optional callbacks (default no-op)

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)
}

// Revenue callback

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

Clean Up

Always destroy ads when you’re done with them:
// Destroy a specific loaded ad
nativeAdLoader.destroy(ad)

// Destroy the loader and all associated resources
nativeAdLoader.destroy()

Native Ad Assets (CloudXNativeAd)

The CloudXNativeAd interface is available via ad.nativeAd in listener callbacks:
PropertyTypeDescription
titleString?Headline text
bodyString?Body / description text
callToActionString?CTA button text (e.g., “Install Now”)
advertiserString?Advertiser name
iconCloudXNativeAdImage?App icon (as Drawable or Uri)
mainImageCloudXNativeAdImage?Main image (static creatives)
mediaViewView?Video/media player view (adapter-provided)
optionsViewView?AdChoices or options view (adapter-provided)
mediaContentAspectRatioFloatAspect ratio of the media content
starRatingDouble?App store rating (0–5)
isVideoContentBooleanWhether the creative is a video
videoDurationDoubleVideo length in seconds (0.0 if unknown)
isExpiredBooleanWhether the ad has expired

Reels Feed Tips

  • Use a ViewPager2 with android:orientation="vertical". Each item should be MATCH_PARENT in both dimensions.
  • Call prepareForReuse() on the CloudXNativeAdView when recycling items.
  • Create one CloudXNativeAdLoader per slot. Load ads sequentially.
  • Destroy ads when no longer needed via destroy(ad).