개요
전면 광고는 화면 전체를 덮는 풀스크린 광고입니다. 자연스러운 전환 시점(예: 게임 레벨 완료, 페이지 이동 등)에 표시하면 효과적입니다.주요 특징
- 화면 전체를 덮는 풀스크린 광고
- 이미지 및 동영상 광고 지원
- 풀스크린 이벤트 콜백 제공
- 로드와 표시를 분리하여 유연한 타이밍 제어
개발 환경에서는 테스트 유닛 ID를 사용하세요:
PUBLIC_TEST_UNIT_ID_INTERSTITIALAdropInterstitialAd
생성자
복사
AdropInterstitialAd({
required String unitId,
AdropInterstitialListener? listener,
})
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
unitId | String | Y | 애드컨트롤 콘솔에서 생성한 유닛 ID |
listener | AdropInterstitialListener | N | 광고 이벤트 리스너 |
속성
| 속성 | 타입 | 설명 |
|---|---|---|
isLoaded | bool | 광고 로드 완료 여부 |
unitId | String | 광고 유닛 ID |
creativeId | String | 크리에이티브 ID |
txId | String | 트랜잭션 ID |
campaignId | String | 캠페인 ID |
destinationURL | String | 목적지 URL |
메서드
| 메서드 | 반환 타입 | 설명 |
|---|---|---|
load() | Future<void> | 광고를 로드합니다 |
show() | Future<void> | 광고를 화면에 표시합니다 |
dispose() | Future<void> | 리소스를 해제합니다 |
기본 사용법
복사
import 'package:flutter/material.dart';
import 'package:adrop_ads_flutter/adrop_ads_flutter.dart';
class InterstitialExample extends StatefulWidget {
const InterstitialExample({super.key});
@override
State<InterstitialExample> createState() => _InterstitialExampleState();
}
class _InterstitialExampleState extends State<InterstitialExample> {
bool isLoaded = false;
AdropInterstitialAd? interstitialAd;
@override
void initState() {
super.initState();
_createInterstitialAd();
}
void _createInterstitialAd() {
interstitialAd = AdropInterstitialAd(
unitId: 'YOUR_UNIT_ID',
listener: AdropInterstitialListener(
onAdReceived: (ad) {
debugPrint('전면 광고 로드 성공: ${ad.creativeId}');
setState(() {
isLoaded = true;
});
},
onAdFailedToReceive: (ad, errorCode) {
debugPrint('전면 광고 로드 실패: $errorCode');
},
onAdClicked: (ad) {
debugPrint('전면 광고 클릭');
},
onAdDidPresentFullScreen: (ad) {
debugPrint('전면 광고 표시됨');
},
onAdDidDismissFullScreen: (ad) {
debugPrint('전면 광고 닫힘');
},
onAdFailedToShowFullScreen: (ad, errorCode) {
debugPrint('전면 광고 표시 실패: $errorCode');
},
),
);
}
void loadAd() {
interstitialAd?.load();
}
void showAd() {
if (isLoaded) {
interstitialAd?.show();
}
}
@override
void dispose() {
interstitialAd?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('전면 광고 예제')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: loadAd,
child: const Text('광고 로드'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: isLoaded ? showAd : null,
child: const Text('광고 표시'),
),
],
),
),
);
}
}
AdropInterstitialListener
전면 광고 이벤트를 처리하는 리스너입니다.콜백 함수
복사
AdropInterstitialListener(
onAdReceived: (AdropAd ad) {
// 광고 로드 성공
},
onAdClicked: (AdropAd ad) {
// 광고 클릭
},
onAdImpression: (AdropAd ad) {
// 광고 노출
},
onAdWillPresentFullScreen: (AdropAd ad) {
// 광고가 표시되기 직전 (iOS 전용)
},
onAdDidPresentFullScreen: (AdropAd ad) {
// 광고가 표시됨
},
onAdWillDismissFullScreen: (AdropAd ad) {
// 광고가 닫히기 직전 (iOS 전용)
},
onAdDidDismissFullScreen: (AdropAd ad) {
// 광고가 닫힘
},
onAdFailedToReceive: (AdropAd ad, AdropErrorCode errorCode) {
// 광고 로드 실패
},
onAdFailedToShowFullScreen: (AdropAd ad, AdropErrorCode errorCode) {
// 광고 표시 실패
},
)
콜백 설명
| 콜백 | 설명 |
|---|---|
onAdReceived | 광고 로드 성공 시 호출 |
onAdClicked | 광고 클릭 시 호출 |
onAdImpression | 광고 노출 시 호출 |
onAdWillPresentFullScreen | 광고가 표시되기 직전 호출 (iOS 전용) |
onAdDidPresentFullScreen | 광고가 표시된 후 호출 |
onAdWillDismissFullScreen | 광고가 닫히기 직전 호출 (iOS 전용) |
onAdDidDismissFullScreen | 광고가 닫힌 후 호출 |
onAdFailedToReceive | 광고 로드 실패 시 호출 |
onAdFailedToShowFullScreen | 광고 표시 실패 시 호출 |
광고 라이프사이클
광고 재생성
전면 광고는 일회성입니다. 한 번 표시된 광고는 다시 표시할 수 없으므로, 새로운 광고를 로드하려면 인스턴스를 재생성해야 합니다.복사
class _InterstitialState extends State<InterstitialWidget> {
bool isLoaded = false;
bool isShown = false;
AdropInterstitialAd? interstitialAd;
@override
void initState() {
super.initState();
_createInterstitialAd();
}
void _createInterstitialAd() {
interstitialAd?.dispose();
interstitialAd = AdropInterstitialAd(
unitId: 'YOUR_UNIT_ID',
listener: AdropInterstitialListener(
onAdReceived: (ad) {
setState(() {
isLoaded = true;
});
},
onAdDidPresentFullScreen: (ad) {
setState(() {
isShown = true;
});
},
onAdDidDismissFullScreen: (ad) {
// 광고가 닫힌 후 새 광고 준비
_createInterstitialAd();
interstitialAd?.load();
},
),
);
setState(() {
isLoaded = false;
isShown = false;
});
}
@override
void dispose() {
interstitialAd?.dispose();
super.dispose();
}
}
에러 처리
복사
class _InterstitialState extends State<InterstitialWidget> {
bool isLoaded = false;
AdropErrorCode? errorCode;
AdropInterstitialAd? interstitialAd;
void _createInterstitialAd() {
interstitialAd = AdropInterstitialAd(
unitId: 'YOUR_UNIT_ID',
listener: AdropInterstitialListener(
onAdReceived: (ad) {
setState(() {
isLoaded = true;
errorCode = null;
});
},
onAdFailedToReceive: (ad, error) {
setState(() {
isLoaded = false;
errorCode = error;
});
_handleError(error);
},
onAdFailedToShowFullScreen: (ad, error) {
setState(() {
errorCode = error;
});
_handleError(error);
},
),
);
}
void _handleError(AdropErrorCode error) {
switch (error) {
case AdropErrorCode.network:
debugPrint('네트워크 오류가 발생했습니다.');
break;
case AdropErrorCode.adNoFill:
debugPrint('노출할 광고가 없습니다.');
break;
case AdropErrorCode.adShown:
debugPrint('이미 표시된 광고입니다.');
break;
default:
debugPrint('오류 발생: ${error.code}');
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: interstitialAd?.load,
child: const Text('광고 로드'),
),
ElevatedButton(
onPressed: isLoaded ? interstitialAd?.show : null,
child: const Text('광고 표시'),
),
if (errorCode != null)
Text(
'에러: ${errorCode?.code}',
style: const TextStyle(color: Colors.red),
),
],
);
}
}
베스트 프랙티스
1. 적절한 타이밍에 표시
전면 광고는 자연스러운 전환 시점에 표시하세요.복사
// 좋은 예: 레벨 완료 후
void onLevelComplete() {
showInterstitialAd();
navigateToNextLevel();
}
// 나쁜 예: 앱 시작 직후
void onAppStart() {
showInterstitialAd(); // 사용자 경험 저하
}
2. 미리 로드하기
광고를 미리 로드해두면 표시 시점에 지연 없이 보여줄 수 있습니다.복사
class GameScreen extends StatefulWidget {
@override
State<GameScreen> createState() => _GameScreenState();
}
class _GameScreenState extends State<GameScreen> {
AdropInterstitialAd? interstitialAd;
bool isAdReady = false;
@override
void initState() {
super.initState();
_preloadAd();
}
void _preloadAd() {
interstitialAd = AdropInterstitialAd(
unitId: 'YOUR_UNIT_ID',
listener: AdropInterstitialListener(
onAdReceived: (ad) {
setState(() {
isAdReady = true;
});
},
onAdDidDismissFullScreen: (ad) {
// 다음 광고 미리 로드
_preloadAd();
},
),
);
interstitialAd?.load();
}
void showAdIfReady() {
if (isAdReady) {
interstitialAd?.show();
setState(() {
isAdReady = false;
});
}
}
@override
void dispose() {
interstitialAd?.dispose();
super.dispose();
}
}
3. 빈도 제한
사용자 경험을 위해 광고 표시 빈도를 제한하세요.복사
class AdManager {
static int _interstitialCount = 0;
static const int _maxInterstitialsPerSession = 3;
static DateTime? _lastInterstitialTime;
static const Duration _minInterval = Duration(minutes: 2);
static bool canShowInterstitial() {
if (_interstitialCount >= _maxInterstitialsPerSession) {
return false;
}
if (_lastInterstitialTime != null) {
final elapsed = DateTime.now().difference(_lastInterstitialTime!);
if (elapsed < _minInterval) {
return false;
}
}
return true;
}
static void onInterstitialShown() {
_interstitialCount++;
_lastInterstitialTime = DateTime.now();
}
}
4. 리소스 관리
사용하지 않는 광고 인스턴스는 반드시 해제하세요.복사
@override
void dispose() {
interstitialAd?.dispose();
super.dispose();
}
전체 예제
복사
import 'package:flutter/material.dart';
import 'package:adrop_ads_flutter/adrop_ads_flutter.dart';
class InterstitialAdPage extends StatefulWidget {
const InterstitialAdPage({super.key});
@override
State<InterstitialAdPage> createState() => _InterstitialAdPageState();
}
class _InterstitialAdPageState extends State<InterstitialAdPage> {
bool isLoaded = false;
bool isLoading = false;
bool isShown = false;
AdropErrorCode? errorCode;
AdropInterstitialAd? interstitialAd;
@override
void initState() {
super.initState();
_createInterstitialAd();
}
void _createInterstitialAd() {
interstitialAd?.dispose();
interstitialAd = AdropInterstitialAd(
unitId: 'PUBLIC_TEST_UNIT_ID_INTERSTITIAL', // 테스트 유닛 ID
listener: AdropInterstitialListener(
onAdReceived: (ad) {
debugPrint('광고 로드 성공');
debugPrint('크리에이티브 ID: ${ad.creativeId}');
debugPrint('캠페인 ID: ${ad.campaignId}');
setState(() {
isLoaded = true;
isLoading = false;
errorCode = null;
});
},
onAdClicked: (ad) {
debugPrint('광고 클릭: ${ad.destinationURL}');
},
onAdImpression: (ad) {
debugPrint('광고 노출: ${ad.creativeId}');
},
onAdWillPresentFullScreen: (ad) {
debugPrint('광고 표시 예정');
},
onAdDidPresentFullScreen: (ad) {
debugPrint('광고 표시됨');
setState(() {
isShown = true;
});
},
onAdWillDismissFullScreen: (ad) {
debugPrint('광고 닫힘 예정');
},
onAdDidDismissFullScreen: (ad) {
debugPrint('광고 닫힘');
// 새 광고 준비
_createInterstitialAd();
},
onAdFailedToReceive: (ad, error) {
debugPrint('광고 로드 실패: $error');
setState(() {
isLoaded = false;
isLoading = false;
errorCode = error;
});
},
onAdFailedToShowFullScreen: (ad, error) {
debugPrint('광고 표시 실패: $error');
setState(() {
errorCode = error;
});
},
),
);
setState(() {
isLoaded = false;
isShown = false;
errorCode = null;
});
}
void loadAd() {
setState(() {
isLoading = true;
errorCode = null;
});
interstitialAd?.load();
}
void showAd() {
if (isLoaded) {
interstitialAd?.show();
}
}
@override
void dispose() {
interstitialAd?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('전면 광고 예제'),
),
body: SafeArea(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 로드 버튼
ElevatedButton(
onPressed: isLoading ? null : loadAd,
child: Text(isLoading ? '로딩 중...' : '광고 로드'),
),
const SizedBox(height: 16),
// 표시 버튼
ElevatedButton(
onPressed: isLoaded ? showAd : null,
child: const Text('광고 표시'),
),
const SizedBox(height: 16),
// 재설정 버튼
TextButton(
onPressed: (isShown || errorCode != null)
? () => _createInterstitialAd()
: null,
child: const Text('재설정'),
),
const SizedBox(height: 24),
// 상태 표시
Text('로드됨: ${isLoaded ? "예" : "아니오"}'),
Text('표시됨: ${isShown ? "예" : "아니오"}'),
// 에러 표시
if (errorCode != null) ...[
const SizedBox(height: 16),
Text(
'에러: ${errorCode?.code}',
style: const TextStyle(color: Colors.red),
),
],
],
),
),
),
);
}
}