메인 콘텐츠로 건너뛰기

개요

네이티브 광고는 앱의 디자인에 맞게 광고 UI를 자유롭게 커스터마이징할 수 있는 광고 포맷입니다. 광고 소재(이미지, 동영상), 제목, 설명, CTA 버튼 등의 요소를 개별적으로 배치하여 자연스러운 사용자 경험을 제공할 수 있습니다.

주요 기능

  • 완전한 UI 커스터마이징: 앱의 디자인 시스템에 맞게 광고 레이아웃을 자유롭게 구성
  • 다양한 미디어 지원: 이미지 및 동영상 광고 소재 지원
  • 유연한 클릭 영역 설정: 전체 클릭 또는 개별 요소별 클릭 처리 가능
  • 프로필 정보 표시: 광고주 프로필 로고, 이름, 링크 지원

클래스 및 인터페이스

AdropNativeAd

네이티브 광고를 로드하고 관리하는 메인 클래스입니다.
unitId
String
required
광고 지면 ID (콘솔에서 발급)
contextId
String
컨텍스트 타겟팅을 위한 ID (선택사항)
listener
AdropNativeAdListener
광고 이벤트를 처리할 리스너
useCustomClick
Boolean
default:"false"
커스텀 클릭 처리 사용 여부

주요 프로퍼티

프로퍼티타입설명
headlineString광고 제목
bodyString광고 본문
iconString아이콘 이미지 URL
coverString커버 이미지 URL
advertiserString광고주 이름
callToActionString행동 유도 문구 (예: “지금 확인하기”)
profileAdropNativeAdProfile광고주 프로필 정보
isLoadedBoolean광고 로드 완료 여부
isDestroyedBoolean광고 제거 여부

AdropNativeAdView

네이티브 광고를 표시할 컨테이너 뷰입니다.
isEntireClick
Boolean
default:"false"
전체 영역 클릭 활성화 여부. true로 설정하면 광고 뷰 전체 영역에서 클릭 이벤트가 발생합니다.

주요 메서드

메서드설명
setIconView(view, listener)아이콘 이미지 뷰 설정 (ImageView 타입)
setHeadLineView(view, listener)제목 텍스트 뷰 설정 (TextView 타입)
setBodyView(view)본문 텍스트 뷰 설정 (TextView 타입)
setMediaView(view)미디어 컨테이너 뷰 설정 (AdropMediaView 타입)
setAdvertiserView(view, listener)광고주명 텍스트 뷰 설정 (TextView 타입)
setCallToActionView(view)CTA 버튼 또는 텍스트 뷰 설정
setProfileLogoView(view, listener)프로필 로고 이미지 뷰 설정 (ImageView 타입)
setProfileNameView(view, listener)프로필 이름 텍스트 뷰 설정 (TextView 타입)
setNativeAd(ad)광고 데이터를 뷰에 바인딩
destroy()리소스 해제

AdropMediaView

광고 이미지 또는 동영상을 표시할 미디어 컨테이너 뷰입니다.
<io.adrop.ads.nativeAd.AdropMediaView
    android:id="@+id/ad_media"
    android:layout_width="match_parent"
    android:layout_height="200dp" />

AdropNativeAdListener

광고 이벤트를 처리하는 인터페이스입니다.
interface AdropNativeAdListener {
    fun onAdReceived(ad: AdropNativeAd)
    fun onAdClick(ad: AdropNativeAd)
    fun onAdFailedToReceive(ad: AdropNativeAd, errorCode: AdropErrorCode)
    fun onAdImpression(ad: AdropNativeAd) // 선택적 구현
}

AdropNativeAdProfile

광고주 프로필 정보를 담는 데이터 클래스입니다.
프로퍼티타입설명
displayLogoString프로필 로고 이미지 URL
displayNameString프로필 표시 이름
linkString프로필 링크 URL

구현 가이드

1. XML 레이아웃 설정

네이티브 광고를 표시할 레이아웃을 정의합니다. AdropNativeAdView를 루트로 하고, 내부에 광고 요소들을 배치합니다.
res/layout/native_ad_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<io.adrop.ads.nativeAd.AdropNativeAdView
    android:id="@+id/native_ad_view"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp">

        <!-- 프로필 영역 -->
        <ImageView
            android:id="@+id/ad_profile_logo"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:scaleType="centerCrop"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/ad_profile_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:textSize="16sp"
            android:textStyle="bold"
            app:layout_constraintStart_toEndOf="@id/ad_profile_logo"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/ad_badge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="4dp"
            android:text="광고"
            android:textSize="12sp"
            app:layout_constraintStart_toEndOf="@id/ad_profile_logo"
            app:layout_constraintTop_toBottomOf="@id/ad_profile_name" />

        <!-- 미디어 영역 -->
        <io.adrop.ads.nativeAd.AdropMediaView
            android:id="@+id/ad_media"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:layout_marginTop="12dp"
            app:layout_constraintTop_toBottomOf="@id/ad_profile_logo" />

        <!-- 광고 내용 -->
        <TextView
            android:id="@+id/ad_headline"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:textSize="18sp"
            android:textStyle="bold"
            app:layout_constraintTop_toBottomOf="@id/ad_media" />

        <TextView
            android:id="@+id/ad_body"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:textSize="14sp"
            app:layout_constraintTop_toBottomOf="@id/ad_headline" />

        <!-- 하단 영역 -->
        <TextView
            android:id="@+id/ad_advertiser"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:textSize="14sp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/ad_body" />

        <Button
            android:id="@+id/ad_call_to_action"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@id/ad_body" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</io.adrop.ads.nativeAd.AdropNativeAdView>

2. 광고 로드 및 표시 (Kotlin)

import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import io.adrop.ads.model.AdropErrorCode
import io.adrop.ads.nativeAd.AdropMediaView
import io.adrop.ads.nativeAd.AdropNativeAd
import io.adrop.ads.nativeAd.AdropNativeAdListener
import io.adrop.ads.nativeAd.AdropNativeAdView

class NativeAdActivity : AppCompatActivity() {

    private lateinit var nativeAd: AdropNativeAd
    private lateinit var nativeAdView: AdropNativeAdView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_native_ad)

        nativeAdView = findViewById(R.id.native_ad_view)
        loadNativeAd()
    }

    private fun loadNativeAd() {
        // 1. 네이티브 광고 인스턴스 생성
        nativeAd = AdropNativeAd(
            context = this,
            unitId = "YOUR_UNIT_ID"  // 실제 유닛 ID로 교체
        )

        // 2. 리스너 설정
        nativeAd.listener = object : AdropNativeAdListener {
            override fun onAdReceived(ad: AdropNativeAd) {
                Log.d("Adrop", "광고 수신 성공")
                populateNativeAdView(ad)
            }

            override fun onAdFailedToReceive(ad: AdropNativeAd, errorCode: AdropErrorCode) {
                Log.e("Adrop", "광고 수신 실패: $errorCode")
            }

            override fun onAdClick(ad: AdropNativeAd) {
                Log.d("Adrop", "광고 클릭됨")
            }

            override fun onAdImpression(ad: AdropNativeAd) {
                Log.d("Adrop", "광고 노출됨")
            }
        }

        // 3. 광고 로드
        nativeAd.load()
    }

    private fun populateNativeAdView(ad: AdropNativeAd) {
        // 프로필 설정
        val profileLogoView = findViewById<ImageView>(R.id.ad_profile_logo)
        Glide.with(this).load(ad.profile.displayLogo).into(profileLogoView)
        nativeAdView.setProfileLogoView(profileLogoView)

        val profileNameView = findViewById<TextView>(R.id.ad_profile_name)
        profileNameView.text = ad.profile.displayName
        nativeAdView.setProfileNameView(profileNameView)

        // 제목 설정
        val headlineView = findViewById<TextView>(R.id.ad_headline)
        headlineView.text = ad.headline
        nativeAdView.setHeadLineView(headlineView)

        // 미디어 설정
        val mediaView = findViewById<AdropMediaView>(R.id.ad_media)
        nativeAdView.setMediaView(mediaView)

        // 본문 설정
        val bodyView = findViewById<TextView>(R.id.ad_body)
        bodyView.text = ad.body
        nativeAdView.setBodyView(bodyView)

        // 광고주 설정
        val advertiserView = findViewById<TextView>(R.id.ad_advertiser)
        advertiserView.text = ad.advertiser
        nativeAdView.setAdvertiserView(advertiserView)

        // CTA 버튼 설정
        val ctaView = findViewById<Button>(R.id.ad_call_to_action)
        ctaView.text = ad.callToAction
        nativeAdView.setCallToActionView(ctaView)

        // 광고 데이터 바인딩
        nativeAdView.setNativeAd(ad)
    }

    override fun onDestroy() {
        // 리소스 해제
        nativeAdView.destroy()
        nativeAd.destroy()
        super.onDestroy()
    }
}

3. 광고 로드 및 표시 (Java)

Java
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.bumptech.glide.Glide;
import io.adrop.ads.model.AdropErrorCode;
import io.adrop.ads.nativeAd.AdropMediaView;
import io.adrop.ads.nativeAd.AdropNativeAd;
import io.adrop.ads.nativeAd.AdropNativeAdListener;
import io.adrop.ads.nativeAd.AdropNativeAdView;

public class NativeAdActivity extends AppCompatActivity {

    private AdropNativeAd nativeAd;
    private AdropNativeAdView nativeAdView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_native_ad);

        nativeAdView = findViewById(R.id.native_ad_view);
        loadNativeAd();
    }

    private void loadNativeAd() {
        // 1. 네이티브 광고 인스턴스 생성
        nativeAd = new AdropNativeAd(
            this,
            "YOUR_UNIT_ID",  // 실제 유닛 ID로 교체
            null  // contextId (선택사항)
        );

        // 2. 리스너 설정
        nativeAd.setListener(new AdropNativeAdListener() {
            @Override
            public void onAdReceived(AdropNativeAd ad) {
                Log.d("Adrop", "광고 수신 성공");
                populateNativeAdView(ad);
            }

            @Override
            public void onAdFailedToReceive(AdropNativeAd ad, AdropErrorCode errorCode) {
                Log.e("Adrop", "광고 수신 실패: " + errorCode);
            }

            @Override
            public void onAdClick(AdropNativeAd ad) {
                Log.d("Adrop", "광고 클릭됨");
            }

            @Override
            public void onAdImpression(AdropNativeAd ad) {
                Log.d("Adrop", "광고 노출됨");
            }
        });

        // 3. 광고 로드
        nativeAd.load();
    }

    private void populateNativeAdView(AdropNativeAd ad) {
        // 프로필 로고 설정
        ImageView profileLogoView = findViewById(R.id.ad_profile_logo);
        Glide.with(this).load(ad.getProfile().getDisplayLogo()).into(profileLogoView);
        nativeAdView.setProfileLogoView(profileLogoView, null);

        // 프로필 이름 설정
        TextView profileNameView = findViewById(R.id.ad_profile_name);
        profileNameView.setText(ad.getProfile().getDisplayName());
        nativeAdView.setProfileNameView(profileNameView, null);

        // 제목 설정
        TextView headlineView = findViewById(R.id.ad_headline);
        headlineView.setText(ad.getHeadline());
        nativeAdView.setHeadLineView(headlineView, null);

        // 미디어 설정
        AdropMediaView mediaView = findViewById(R.id.ad_media);
        nativeAdView.setMediaView(mediaView);

        // 본문 설정
        TextView bodyView = findViewById(R.id.ad_body);
        bodyView.setText(ad.getBody());
        nativeAdView.setBodyView(bodyView);

        // 광고주 설정
        TextView advertiserView = findViewById(R.id.ad_advertiser);
        advertiserView.setText(ad.getAdvertiser());
        nativeAdView.setAdvertiserView(advertiserView, null);

        // CTA 버튼 설정
        Button ctaView = findViewById(R.id.ad_call_to_action);
        ctaView.setText(ad.getCallToAction());
        nativeAdView.setCallToActionView(ctaView);

        // 광고 데이터 바인딩
        nativeAdView.setNativeAd(ad);
    }

    @Override
    protected void onDestroy() {
        // 리소스 해제
        if (nativeAdView != null) {
            nativeAdView.destroy();
        }
        if (nativeAd != null) {
            nativeAd.destroy();
        }
        super.onDestroy();
    }
}

고급 기능

전체 클릭 영역 설정

광고 뷰 전체 영역에서 클릭 이벤트가 발생하도록 설정할 수 있습니다.
nativeAdView.isEntireClick = true
isEntireClicktrue로 설정하면 광고 뷰 전체가 클릭 가능한 영역이 됩니다. 개별 요소의 클릭 리스너는 동작하지 않습니다.

개별 요소 클릭 리스너

특정 광고 요소에 커스텀 클릭 리스너를 설정할 수 있습니다.
// 광고주 클릭 시 커스텀 동작
nativeAdView.setAdvertiserView(advertiserView) {
    Log.d("Adrop", "광고주 클릭")
    // 커스텀 동작 구현
}

// 프로필 로고 클릭 시 커스텀 동작
nativeAdView.setProfileLogoView(profileLogoView) {
    Log.d("Adrop", "프로필 로고 클릭")
    // 커스텀 동작 구현
}

컨텍스트 타겟팅

특정 컨텍스트에 맞는 광고를 요청할 수 있습니다.
val nativeAd = AdropNativeAd(
    context = this,
    unitId = "YOUR_UNIT_ID",
    contextId = "SPORTS_NEWS"  // 컨텍스트 ID
)

RecyclerView에서 사용하기

RecyclerView의 아이템으로 네이티브 광고를 표시할 수 있습니다.
RecyclerView Adapter
class ContentAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    companion object {
        const val VIEW_TYPE_CONTENT = 0
        const val VIEW_TYPE_AD = 1
        const val AD_INTERVAL = 5  // 5개 아이템마다 광고 표시
    }

    private val items = mutableListOf<Any>()
    private val nativeAds = mutableMapOf<Int, AdropNativeAd>()

    override fun getItemViewType(position: Int): Int {
        return if (position % (AD_INTERVAL + 1) == AD_INTERVAL) {
            VIEW_TYPE_AD
        } else {
            VIEW_TYPE_CONTENT
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            VIEW_TYPE_AD -> {
                val view = LayoutInflater.from(parent.context)
                    .inflate(R.layout.item_native_ad, parent, false)
                NativeAdViewHolder(view)
            }
            else -> {
                val view = LayoutInflater.from(parent.context)
                    .inflate(R.layout.item_content, parent, false)
                ContentViewHolder(view)
            }
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is NativeAdViewHolder -> loadNativeAd(holder, position)
            is ContentViewHolder -> holder.bind(items[position])
        }
    }

    private fun loadNativeAd(holder: NativeAdViewHolder, position: Int) {
        // 이미 로드된 광고가 있으면 재사용
        nativeAds[position]?.let { ad ->
            if (ad.isLoaded) {
                holder.bind(ad)
                return
            }
        }

        // 새 광고 로드
        val nativeAd = AdropNativeAd(holder.itemView.context, "YOUR_UNIT_ID")
        nativeAd.listener = object : AdropNativeAdListener {
            override fun onAdReceived(ad: AdropNativeAd) {
                nativeAds[position] = ad
                holder.bind(ad)
            }

            override fun onAdFailedToReceive(ad: AdropNativeAd, errorCode: AdropErrorCode) {
                Log.e("Adrop", "광고 로드 실패: $errorCode")
            }

            override fun onAdClick(ad: AdropNativeAd) {
                Log.d("Adrop", "광고 클릭")
            }
        }
        nativeAd.load()
    }

    class NativeAdViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val nativeAdView: AdropNativeAdView = itemView.findViewById(R.id.native_ad_view)

        fun bind(ad: AdropNativeAd) {
            val profileLogo = itemView.findViewById<ImageView>(R.id.ad_profile_logo)
            Glide.with(itemView.context).load(ad.profile.displayLogo).into(profileLogo)
            nativeAdView.setProfileLogoView(profileLogo)

            val profileName = itemView.findViewById<TextView>(R.id.ad_profile_name)
            profileName.text = ad.profile.displayName
            nativeAdView.setProfileNameView(profileName)

            val headline = itemView.findViewById<TextView>(R.id.ad_headline)
            headline.text = ad.headline
            nativeAdView.setHeadLineView(headline)

            val media = itemView.findViewById<AdropMediaView>(R.id.ad_media)
            nativeAdView.setMediaView(media)

            val body = itemView.findViewById<TextView>(R.id.ad_body)
            body.text = ad.body
            nativeAdView.setBodyView(body)

            val advertiser = itemView.findViewById<TextView>(R.id.ad_advertiser)
            advertiser.text = ad.advertiser
            nativeAdView.setAdvertiserView(advertiser)

            val cta = itemView.findViewById<Button>(R.id.ad_call_to_action)
            cta.text = ad.callToAction
            nativeAdView.setCallToActionView(cta)

            nativeAdView.setNativeAd(ad)
        }
    }

    fun destroy() {
        nativeAds.values.forEach { it.destroy() }
        nativeAds.clear()
    }
}

테스트 유닛 ID

개발 및 테스트 시 다음 테스트 유닛 ID를 사용하세요.
포맷테스트 유닛 ID
네이티브 (이미지)PUBLIC_TEST_UNIT_ID_NATIVE
네이티브 비디오 (16:9)PUBLIC_TEST_UNIT_ID_NATIVE_VIDEO_16_9
네이티브 비디오 (9:16)PUBLIC_TEST_UNIT_ID_NATIVE_VIDEO_9_16
프로덕션 배포 전에 반드시 실제 유닛 ID로 교체하세요.

라이프사이클 관리

Activity/Fragment에서 리소스 해제

네이티브 광고는 메모리 누수를 방지하기 위해 사용이 끝나면 반드시 해제해야 합니다.
override fun onDestroy() {
    nativeAdView.destroy()
    nativeAd.destroy()
    super.onDestroy()
}

RecyclerView에서 리소스 해제

RecyclerView Adapter에서 광고를 사용하는 경우, 액티비티나 프래그먼트가 종료될 때 모든 광고를 해제해야 합니다.
override fun onDestroy() {
    adapter.destroy()
    super.onDestroy()
}

모범 사례

1. 필수 요소만 표시

모든 광고 요소를 표시할 필요는 없습니다. 앱의 디자인에 맞게 필요한 요소만 선택적으로 사용하세요.
// 최소 구성 예시 (미디어 + CTA만 사용)
nativeAdView.setMediaView(mediaView)
nativeAdView.setCallToActionView(ctaView)
nativeAdView.setNativeAd(ad)

2. 이미지 로딩 라이브러리 사용

아이콘, 커버, 프로필 이미지를 표시할 때는 Glide, Coil 등의 이미지 로딩 라이브러리를 사용하세요.
// Glide 사용 예시
Glide.with(context)
    .load(ad.icon)
    .placeholder(R.drawable.placeholder)
    .error(R.drawable.error)
    .into(iconView)

3. 광고 뷰 재사용

RecyclerView에서 광고를 표시할 때는 광고 인스턴스를 캐싱하여 재사용하세요.

4. 적절한 광고 위치

사용자 경험을 해치지 않는 선에서 자연스럽게 광고를 배치하세요.
  • 콘텐츠 피드: 5~10개 아이템마다 1개의 광고
  • 상세 화면: 콘텐츠 하단에 배치
  • 스크롤 뷰: 자연스러운 콘텐츠 흐름에 맞춰 배치

5. 에러 처리

광고 로드 실패에 대비하여 적절한 폴백 처리를 구현하세요.
override fun onAdFailedToReceive(ad: AdropNativeAd, errorCode: AdropErrorCode) {
    when (errorCode) {
        AdropErrorCode.ERROR_CODE_AD_NO_FILL -> {
            // 광고 없음 - 광고 영역 숨기기
            nativeAdView.visibility = View.GONE
        }
        AdropErrorCode.ERROR_CODE_NETWORK -> {
            // 네트워크 오류 - 재시도 로직
            Handler(Looper.getMainLooper()).postDelayed({
                nativeAd.load()
            }, 3000)
        }
        else -> {
            Log.e("Adrop", "광고 로드 실패: $errorCode")
        }
    }
}

완전한 예제

import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.bumptech.glide.Glide
import io.adrop.ads.model.AdropErrorCode
import io.adrop.ads.nativeAd.AdropMediaView
import io.adrop.ads.nativeAd.AdropNativeAd
import io.adrop.ads.nativeAd.AdropNativeAdListener
import io.adrop.ads.nativeAd.AdropNativeAdView

class NativeAdExampleActivity : AppCompatActivity() {

    private lateinit var nativeAd: AdropNativeAd
    private lateinit var nativeAdView: AdropNativeAdView
    private lateinit var loadingView: View
    private lateinit var errorView: View

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_native_ad_example)

        nativeAdView = findViewById(R.id.native_ad_view)
        loadingView = findViewById(R.id.loading_view)
        errorView = findViewById(R.id.error_view)

        findViewById<Button>(R.id.retry_button).setOnClickListener {
            loadNativeAd()
        }

        loadNativeAd()
    }

    private fun loadNativeAd() {
        showLoading()

        nativeAd = AdropNativeAd(
            context = this,
            unitId = "PUBLIC_TEST_UNIT_ID_NATIVE"
        )

        nativeAd.listener = object : AdropNativeAdListener {
            override fun onAdReceived(ad: AdropNativeAd) {
                Log.d("Adrop", "광고 수신: unitId=${ad.unitId}, txId=${ad.txId}")
                populateNativeAdView(ad)
                showAd()
            }

            override fun onAdFailedToReceive(ad: AdropNativeAd, errorCode: AdropErrorCode) {
                Log.e("Adrop", "광고 수신 실패: $errorCode")
                showError()
            }

            override fun onAdClick(ad: AdropNativeAd) {
                Log.d("Adrop", "광고 클릭: txId=${ad.txId}")
            }

            override fun onAdImpression(ad: AdropNativeAd) {
                Log.d("Adrop", "광고 노출: txId=${ad.txId}")
            }
        }

        nativeAd.load()
    }

    private fun populateNativeAdView(ad: AdropNativeAd) {
        // 전체 클릭 영역 활성화 (선택사항)
        // nativeAdView.isEntireClick = true

        // 프로필 로고
        val profileLogoView = findViewById<ImageView>(R.id.ad_profile_logo)
        Glide.with(this)
            .load(ad.profile.displayLogo)
            .circleCrop()
            .into(profileLogoView)
        nativeAdView.setProfileLogoView(profileLogoView)

        // 프로필 이름
        val profileNameView = findViewById<TextView>(R.id.ad_profile_name)
        profileNameView.text = ad.profile.displayName
        nativeAdView.setProfileNameView(profileNameView)

        // 제목
        val headlineView = findViewById<TextView>(R.id.ad_headline)
        headlineView.text = ad.headline
        nativeAdView.setHeadLineView(headlineView)

        // 미디어 (이미지 또는 동영상)
        val mediaView = findViewById<AdropMediaView>(R.id.ad_media)
        nativeAdView.setMediaView(mediaView)

        // 본문
        val bodyView = findViewById<TextView>(R.id.ad_body)
        bodyView.text = ad.body
        nativeAdView.setBodyView(bodyView)

        // 광고주
        val advertiserView = findViewById<TextView>(R.id.ad_advertiser)
        advertiserView.text = ad.advertiser
        nativeAdView.setAdvertiserView(advertiserView) {
            Log.d("Adrop", "광고주 클릭: ${ad.advertiser}")
        }

        // CTA 버튼
        val ctaView = findViewById<Button>(R.id.ad_call_to_action)
        ctaView.text = ad.callToAction
        nativeAdView.setCallToActionView(ctaView)

        // 광고 데이터 바인딩
        nativeAdView.setNativeAd(ad)
    }

    private fun showLoading() {
        loadingView.visibility = View.VISIBLE
        nativeAdView.visibility = View.GONE
        errorView.visibility = View.GONE
    }

    private fun showAd() {
        loadingView.visibility = View.GONE
        nativeAdView.visibility = View.VISIBLE
        errorView.visibility = View.GONE
    }

    private fun showError() {
        loadingView.visibility = View.GONE
        nativeAdView.visibility = View.GONE
        errorView.visibility = View.VISIBLE
    }

    override fun onDestroy() {
        nativeAdView.destroy()
        nativeAd.destroy()
        super.onDestroy()
    }
}

다음 단계