메인 콘텐츠로 건너뛰기

네이티브 광고 형태 소개

  • 광고 뷰를 미디에이션 SDK가 구현해주는 타 광고 형태와 달리 네이티브 광고 형태는 구성 요소들을 전달받아 앱에서 직접 광고 뷰를 구현합니다.
  • UI/UX 기반으로 레이아웃을 직접 구현하므로써 위화감을 적게 만들 수 있다는 것이 가장 큰 특징입니다. 단, 유저가 광고가 아닌 컨텐츠로써 착각하는 경우를 방지하기 위해 광고 표시와 함께 최소한의 차별성은 부여해야합니다.
Native Example Elements Ko Pn
네이티브 광고 필수 요소 4가지네이티브 광고는 앱 UI에 맞게 자유롭게 디자인할 수 있지만, 아래의 4가지 필수 요소는 반드시 포함해야 합니다. 이는 사용자가 광고임을 명확히 인지하도록 하고, 광고주가 기대하는 최소한의 광고 효과를 보장하기 위한 광고 정책입니다.
  1. 광고 표기 : 사용자가 광고임을 명확히 인지할 수 있도록 광고 영역에 “AD”, “광고” 등의 표기를 추가해 주세요.
  2. AdChoices 아이콘 : AdChoices 아이콘은 사용자가 광고를 식별하고 제어할 수 있도록 제공되는 아이콘으로, 일반적으로 ’ⓘ’ 모양으로 표시됩니다. 해당 아이콘은 DARO SDK에서 자동으로 삽입되므로 별도 구현은 필요하지 않지만, 다른 UI 요소에 가려지지 않도록 광고 뷰를 구성해 주세요. 광고 소스(디맨드)에 따라 아이콘의 형태나 동작이 다를 수 있습니다.
  3. 광고 제목 (타이틀) : 광고의 제목을 표시해야 합니다.
  4. 클릭 유도 문안(CTA) : “설치”, “열기”, “다운로드” 등의 CTA(Call to Action) 버튼을 반드시 포함해 주세요. 버튼의 크기나 형태는 자유롭게 구성할 수 있으며, 상황에 따라 텍스트 필드로 대체 가능합니다. 광고 소스(디맨드)에서 CTA 문구를 제공하므로, 특정 문구를 고정할 필요는 없습니다.

네이티브 팩토리 등록

Flutter에서 네이티브 광고를 사용하려면 네이티브 플랫폼(iOS/Android)에서 네이티브 광고 팩토리를 등록해야 합니다. factoryId는 네이티브 플랫폼에서 등록한 팩토리의 식별자입니다.
1

광고 레이아웃 XML 생성

android/app/src/main/res/layout/ 에 네이티브 광고 레이아웃 파일을 생성합니다.
sample_native_ad.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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="400dp">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:cardCornerRadius="12dp"
        app:cardElevation="4dp"
        app:cardBackgroundColor="#1E1E1E">

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

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:paddingBottom="12dp">

                <ImageView
                    android:id="@+id/ad_app_icon"
                    android:layout_width="56dp"
                    android:layout_height="56dp"
                    android:scaleType="centerCrop" />

                <LinearLayout
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:layout_marginStart="12dp"
                    android:orientation="vertical">

                    <TextView
                        android:id="@+id/ad_headline"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:textSize="16sp"
                        android:textStyle="bold"
                        android:maxLines="2"
                        android:ellipsize="end" />

                    <TextView
                        android:id="@+id/ad_advertiser"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:textSize="13sp"
                        android:layout_marginTop="4dp" />
                </LinearLayout>
            </LinearLayout>

            <FrameLayout
                android:id="@+id/ad_media"
                android:layout_width="match_parent"
                android:layout_height="180dp" />

            <TextView
                android:id="@+id/ad_body"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="12dp"
                android:textSize="14sp"
                android:maxLines="2"
                android:ellipsize="end" />

            <Button
                android:id="@+id/ad_call_to_action"
                android:layout_width="match_parent"
                android:layout_height="44dp"
                android:layout_marginTop="12dp"
                android:textSize="16sp"
                android:textStyle="bold" />
        </LinearLayout>
    </androidx.cardview.widget.CardView>
</FrameLayout>
2

DaroNativeAdFactory 구현

DaroNativeAdFactory 인터페이스를 구현하는 클래스를 생성합니다.
SampleNativeAdFactory.kt
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import so.daro.flutter.native.DaroNativeAdFactory
import droom.daro.core.model.DaroNativeAdBinder

class SampleNativeAdFactory(private val context: Context) : DaroNativeAdFactory {

    override fun createNativeAdView(): View {
        return LayoutInflater.from(context).inflate(R.layout.sample_native_ad, null)
    }

    override fun createAdBinder(view: View): DaroNativeAdBinder {
        return DaroNativeAdBinder.Builder(view)
            .setTitleViewId(R.id.ad_headline)
            .setBodyTextViewId(R.id.ad_body)
            .setIconViewId(R.id.ad_app_icon)
            .setMediaViewGroupId(R.id.ad_media)
            .setCallToActionViewId(R.id.ad_call_to_action)
            .build()
    }
}
3

MainActivity에서 팩토리 등록

MainActivityconfigureFlutterEngine에서 팩토리를 등록합니다.
MainActivity.kt
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import so.daro.flutter.DaroFlutterPlugin

class MainActivity: FlutterActivity() {
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        DaroFlutterPlugin.registerNativeAdFactory(
            SampleNativeAdFactory(this),
            "sample_native_ad"
        )
    }
}
Flutter의 DaroNativeAdWidget에 전달하는 factoryId는 네이티브 플랫폼에서 등록한 팩토리 ID와 정확히 일치해야 합니다.

네이티브 광고 위젯 생성하기

import 'package:daro_flutter/daro_flutter.dart';
DaroNativeAdWidget(
  adUnitId: '{YOUR_AD_UNIT_ID}',
  factoryId: '{YOUR_FACTORY_ID}',
  onAdLoaded: (adInfo) {
    print('Native ad loaded: ${adInfo.adUnitId}');
  },
  onAdFailedToLoad: (error) {
    print('Native ad failed to load: ${error.message}');
  },
  onAdClicked: (adInfo) {
    print('Native ad clicked');
  },
  onAdImpression: (adInfo) {
    print('Native ad impression');
  },
)

콜백 설명

콜백설명
onAdLoaded광고가 성공적으로 로드되었을 때 호출됩니다
onAdFailedToLoad광고 로드에 실패했을 때 호출됩니다
onAdClicked사용자가 광고를 클릭했을 때 호출됩니다
onAdImpression광고 노출이 기록되었을 때 호출됩니다

LINE 네이티브 광고

  • LINE 네이티브 광고는 앱의 피드나 리스트에 자연스럽게 삽입되는 소형 네이티브 광고 형태입니다.
  • 일반 네이티브 광고보다 컴팩트한 형태로, 리스트 아이템 사이에 삽입하기에 적합합니다.
  • 광고 높이는 36dp (Android) / 36pt (iOS) 로 고정됩니다.
  • 스타일을 커스터마이징하여 앱의 UI에 맞게 조정할 수 있습니다.
LINE 네이티브 광고 예시

LINE 네이티브 광고 위젯 생성하기

DaroLineNativeAdWidget(
  adUnitId: '{YOUR_AD_UNIT_ID}',
  onAdLoaded: (adInfo) {
    print('Line native ad loaded: ${adInfo.adUnitId}');
  },
  onAdFailedToLoad: (error) {
    print('Line native ad failed to load: ${error.message}');
  },
  onAdClicked: (adInfo) {
    print('Line native ad clicked');
  },
  onAdImpression: (adInfo) {
    print('Line native ad impression');
  },
)

콜백 설명

콜백설명
onAdLoaded광고가 성공적으로 로드되었을 때 호출됩니다
onAdFailedToLoad광고 로드에 실패했을 때 호출됩니다
onAdClicked사용자가 광고를 클릭했을 때 호출됩니다
onAdImpression광고 노출이 기록되었을 때 호출됩니다

스타일 커스터마이징

DaroLineNativeAdStyle을 사용하여 LINE 네이티브 광고의 색상을 커스터마이징할 수 있습니다.
DaroLineNativeAdWidget(
  adUnitId: '{YOUR_AD_UNIT_ID}',
  style: DaroLineNativeAdStyle(
    backgroundColor: '#FFFFFF',
    contentColor: '#000000',
    adMarkLabelTextColor: '#FFFFFF',
    adMarkLabelBackgroundColor: '#888888',
  ),
  onAdLoaded: (adInfo) {
    print('Line native ad loaded');
  },
  onAdFailedToLoad: (error) {
    print('Line native ad failed: ${error.message}');
  },
)

스타일 속성

속성설명
backgroundColor광고 전체 배경색
contentColor광고 콘텐츠 텍스트 색상
adMarkLabelTextColor광고 마크 텍스트 색상
adMarkLabelBackgroundColor광고 마크 배경색