📰 Native (Rotator)

Podstawowe użycie
private lateinit var nativeRotator: NativeAdRotator

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    nativeRotator = NativeAdRotator(
        context = requireContext(),
        zoneName = "feed",
        callbackName = "default",
        explicitProvider = null,      // lub "admob"
        explicitAdUnit = null,        // lub konkretny adUnit
        fadeDurationMs = 250L,        // animacja cross-fade
        loadingFadeDurationMs = 180L  // animacja loadingu
    )

    nativeRotator.attach(
        adContainer = binding.nativeContainer,
        loading = binding.loadingView  // opcjonalne
    )

    nativeRotator.start()
}

override fun onStop() {
    nativeRotator.stop()
    super.onStop()
}

override fun onDestroyView() {
    nativeRotator.destroy()
    super.onDestroyView()
}

Loading View

Możesz przekazać własny widok ładowania, który będzie automatycznie pokazywany/ukrywany:

Layout z loading view
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <!-- Kontener na reklamę natywną -->
    <FrameLayout
        android:id="@+id/nativeContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="250dp" />

    <!-- Loading view - pokazywany podczas ładowania -->
    <LinearLayout
        android:id="@+id/loadingView"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:gravity="center"
        android:visibility="gone"
        android:background="#F5F5F5">

        <ProgressBar
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:indeterminate="true" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Ładowanie..." />

    </LinearLayout>

</FrameLayout>

Parametry animacji

ParametrDomyślnieOpis
fadeDurationMs250msCzas cross-fade między reklamami
loadingFadeDurationMs180msCzas fade-in/fade-out loading view
💡 Tip: Użyj Facebook Shimmer dla lepszego UX ładowania! implementation 'com.facebook.shimmer:shimmer:0.5.0'

🎨 Native (Custom Binder)

Możesz użyć własnego layoutu dla reklam natywnych za pomocą NativeAdViewBinder.Builder:

1. Layout XML (my_native_ad.xml)
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="12dp">

        <!-- Plakietka "Reklama" - wymagana! -->
        <TextView
            android:id="@+id/ad_attribution"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#FFCC00"
            android:text="AD"
            android:textSize="10sp" />

        <TextView
            android:id="@+id/ad_headline"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textStyle="bold" />

        <ImageView
            android:id="@+id/ad_icon"
            android:layout_width="40dp"
            android:layout_height="40dp" />

        <TextView
            android:id="@+id/ad_body"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <com.google.android.gms.ads.nativead.MediaView
            android:id="@+id/ad_media"
            android:layout_width="match_parent"
            android:layout_height="180dp" />

        <Button
            android:id="@+id/ad_cta"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <com.google.android.gms.ads.nativead.AdChoicesView
            android:id="@+id/ad_choices"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>
2. Tworzenie bindera
val myNativeBinder = NativeAdViewBinder.Builder(R.layout.my_native_ad)
    .bindHeadline(R.id.ad_headline)           // TextView - nagłówek (wymagany)
    .bindBody(R.id.ad_body)                   // TextView - opis
    .bindIcon(R.id.ad_icon)                   // ImageView - ikona
    .bindMedia(R.id.ad_media)                 // MediaView - video/obraz
    .bindCallToAction(R.id.ad_cta)            // Button - przycisk CTA
    .bindAdvertiser(R.id.ad_advertiser)       // TextView - reklamodawca
    .bindAdChoices(R.id.ad_choices)           // AdChoicesView - wymagane!
    .bindAttribution(R.id.ad_attribution, "Reklama")
    .build()

// Użycie w NativeAdRotator
nativeRotator = NativeAdRotator(
    context = requireContext(),
    zoneName = "feed",
    binder = myNativeBinder  // ← Twój binder!
)
⚠️ Ważne: Root layoutu musi być NativeAdView z pakietu com.google.android.gms.ads.nativead!

📺 Interstitial

Pokazywanie interstitiala
lifecycleScope.launch {
    val shown = FullscreenRotator.showInterstitial(
        activity = this@MainActivity,
        zone = "default",
        callbackName = "default",
        explicitAdUnit = null,       // lub konkretny adUnit
        explicitProviders = null     // lub listOf("admob")
    )

    if (shown) {
        Log.d("Ad", "Interstitial wyświetlony")
    } else {
        Log.d("Ad", "Brak reklamy do wyświetlenia")
    }
}

🎁 Rewarded

Pokazywanie rewarded
lifecycleScope.launch {
    val result = FullscreenRotator.showRewarded(
        activity = this@MainActivity,
        zone = "default",
        callbackName = "default"
    )

    when (result) {
        is RewardResult.Earned -> {
            // Użytkownik obejrzał całą reklamę
            addCoins(result.amount.toInt())
            Toast.makeText(
                this,
                "Otrzymałeś ${result.amount} ${result.type}!",
                Toast.LENGTH_SHORT
            ).show()
        }
        is RewardResult.NotEarned -> {
            // Użytkownik zamknął przed końcem
            Toast.makeText(
                this,
                "Obejrzyj do końca aby otrzymać nagrodę",
                Toast.LENGTH_SHORT
            ).show()
        }
        is RewardResult.Failed -> {
            // Błąd ładowania
            Log.e("Ad", "Failed to load rewarded: ${result.error}")
        }
    }
}

RewardResult

TypPolaOpis
Earnedtype, amountNagroda przyznana
NotEarned-Zamknięto przed końcem
FailederrorBłąd ładowania