Documentation Index
Fetch the complete documentation index at: https://docs.adrop.io/llms.txt
Use this file to discover all available pages before exploring further.
ネイティブ広告は、アプリのコンテンツと自然に調和するようにカスタマイズできる広告です。AdropNativeAdとAdropNativeAdViewを使用して、アプリのUIに合わせて広告を構成できます。
主な特徴
- アプリデザインに合わせたカスタムレイアウト構成が可能
- ヘッドライン、本文、CTAボタン、プロフィールなど様々な要素を提供
- 画像およびHTMLクリエイティブをサポート
- カスタムクリック処理をサポート
- バックフィル広告をサポート
開発環境ではテストユニットIDを使用してください: PUBLIC_TEST_UNIT_ID_NATIVE
AdropNativeAd
コンストラクタ
AdropNativeAd({
required String unitId,
bool useCustomClick = false,
AdropNativeListener? listener,
})
パラメータ
| パラメータ | タイプ | 必須 | 説明 |
|---|
unitId | String | Y | Ad Controlコンソールで作成したユニットID |
useCustomClick | bool | N | カスタムクリック処理を使用するかどうか(デフォルト: false) |
listener | AdropNativeListener | N | 広告イベントリスナー |
プロパティ
| プロパティ | タイプ | 説明 |
|---|
isLoaded | bool | 広告のロード完了状態 |
unitId | String | 広告ユニットID |
creativeId | String | クリエイティブID |
txId | String | トランザクションID |
campaignId | String | キャンペーンID |
destinationURL | String | 遷移先URL |
properties | AdropNativeProperties | ネイティブ広告プロパティ |
creativeSize | CreativeSize | クリエイティブサイズ |
isBackfilled | bool | バックフィル広告かどうか |
browserTarget | BrowserTarget? | ブラウザターゲット(外部または内部) |
メソッド
| メソッド | 戻り値の型 | 説明 |
|---|
load() | Future<void> | 広告をロードします |
他の広告タイプ(AdropInterstitialAd、AdropRewardedAd、AdropPopupAd)とは異なり、AdropNativeAdはdispose()メソッドを提供しません。
新しい広告をロードするには、新しいAdropNativeAdインスタンスを作成してください。以前のインスタンスのリソースはガベージコレクターによって自動的に解放されます。
AdropNativeAdView
ネイティブ広告を画面に表示するウィジェットです。
コンストラクタ
AdropNativeAdView({
required AdropNativeAd? ad,
required Widget child,
})
パラメータ
| パラメータ | タイプ | 必須 | 説明 |
|---|
ad | AdropNativeAd? | Y | ロードされたネイティブ広告オブジェクト |
child | Widget | Y | 広告コンテンツを表示する子ウィジェット |
AdropNativeProperties
ネイティブ広告のコンテンツプロパティです。
プロパティ
| プロパティ | タイプ | 説明 |
|---|
headline | String? | 広告タイトル |
body | String? | 広告本文 |
creative | String? | HTMLクリエイティブコンテンツ |
asset | String? | 画像アセットURL |
destinationURL | String? | クリック時の遷移先URL |
callToAction | String? | CTAボタンテキスト |
profile | AdropNativeProfile? | 広告主プロフィール情報 |
extra | Map<String, String> | 追加のカスタムフィールド |
isBackfilled | bool | バックフィル広告かどうか |
AdropNativeProfile
| プロパティ | タイプ | 説明 |
|---|
displayName | String? | 広告主名 |
displayLogo | String? | 広告主ロゴ画像URL |
基本的な使い方
import 'package:flutter/material.dart';
import 'package:adrop_ads_flutter/adrop_ads_flutter.dart';
class NativeAdExample extends StatefulWidget {
const NativeAdExample({super.key});
@override
State<NativeAdExample> createState() => _NativeAdExampleState();
}
class _NativeAdExampleState extends State<NativeAdExample> {
bool isLoaded = false;
AdropNativeAd? nativeAd;
@override
void initState() {
super.initState();
_createNativeAd();
}
void _createNativeAd() {
nativeAd = AdropNativeAd(
unitId: 'YOUR_UNIT_ID',
listener: AdropNativeListener(
onAdReceived: (ad) {
debugPrint('ネイティブ広告受信成功: ${ad.creativeId}');
setState(() {
isLoaded = true;
});
},
onAdClicked: (ad) {
debugPrint('ネイティブ広告クリック: ${ad.creativeId}');
},
onAdImpression: (ad) {
debugPrint('ネイティブ広告表示: ${ad.creativeId}');
},
onAdFailedToReceive: (ad, errorCode) {
debugPrint('ネイティブ広告受信失敗: $errorCode');
setState(() {
isLoaded = false;
});
},
),
);
// 広告をロード
nativeAd?.load();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('ネイティブ広告サンプル')),
body: SingleChildScrollView(
child: Column(
children: [
// メインコンテンツ
const Padding(
padding: EdgeInsets.all(16),
child: Text('メインコンテンツ'),
),
// ネイティブ広告
if (isLoaded) _buildNativeAdView(),
],
),
),
);
}
Widget _buildNativeAdView() {
return AdropNativeAdView(
ad: nativeAd,
child: Container(
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 広告主プロフィール
if (nativeAd?.properties.profile != null)
Row(
children: [
if (nativeAd?.properties.profile?.displayLogo != null)
Image.network(
nativeAd!.properties.profile!.displayLogo!,
width: 24,
height: 24,
),
const SizedBox(width: 8),
Text(nativeAd?.properties.profile?.displayName ?? ''),
],
),
const SizedBox(height: 8),
// ヘッドライン
if (nativeAd?.properties.headline != null)
Text(
nativeAd!.properties.headline!,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
// 本文
if (nativeAd?.properties.body != null)
Text(nativeAd!.properties.body!),
const SizedBox(height: 8),
// 画像アセット
if (nativeAd?.properties.asset != null)
Image.network(
nativeAd!.properties.asset!,
width: double.infinity,
fit: BoxFit.cover,
),
const SizedBox(height: 8),
// CTAボタン
if (nativeAd?.properties.callToAction != null)
ElevatedButton(
onPressed: () {},
child: Text(nativeAd!.properties.callToAction!),
),
],
),
),
);
}
}
AdropNativeListener
ネイティブ広告イベントを処理するリスナーです。
コールバック関数
AdropNativeListener(
onAdReceived: (AdropNativeAd ad) {
// 広告受信成功
},
onAdClicked: (AdropNativeAd ad) {
// 広告クリック
},
onAdImpression: (AdropNativeAd ad) {
// 広告表示
},
onAdFailedToReceive: (AdropNativeAd ad, AdropErrorCode errorCode) {
// 広告受信失敗
},
onAdVideoStart: (AdropNativeAd ad) {
// 動画広告の再生開始
},
onAdVideoEnd: (AdropNativeAd ad) {
// 動画広告の再生終了
},
)
コールバックの説明
| コールバック | 説明 |
|---|
onAdReceived | 広告受信成功時に呼び出し |
onAdClicked | 広告クリック時に呼び出し |
onAdImpression | 広告表示時に呼び出し |
onAdFailedToReceive | 広告受信失敗時に呼び出し |
onAdVideoStart | 動画広告の再生開始時に呼び出し |
onAdVideoEnd | 動画広告の再生終了時に呼び出し |
カスタムクリック処理
動画クリエイティブやカスタムクリック動作が必要な場合はuseCustomClickを使用します。
nativeAd = AdropNativeAd(
unitId: 'YOUR_UNIT_ID',
useCustomClick: true, // カスタムクリックを有効化
listener: AdropNativeListener(
onAdReceived: (ad) {
setState(() {
isLoaded = true;
});
},
onAdClicked: (ad) {
// カスタムクリック動作を処理
debugPrint('広告クリック: ${ad.destinationURL}');
},
),
);
useCustomClickがtrueの場合、子ウィジェットのクリックイベントが広告クリックとして処理されます。
HTMLクリエイティブの表示
ネイティブ広告にHTMLクリエイティブが含まれている場合、WebViewを使用して表示できます。
import 'package:webview_flutter/webview_flutter.dart';
class NativeWithWebView extends StatefulWidget {
const NativeWithWebView({super.key});
@override
State<NativeWithWebView> createState() => _NativeWithWebViewState();
}
class _NativeWithWebViewState extends State<NativeWithWebView> {
bool isLoaded = false;
AdropNativeAd? nativeAd;
late final WebViewController webViewController;
@override
void initState() {
super.initState();
// WebViewコントローラーの初期化
webViewController = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted);
_createNativeAd();
}
void _createNativeAd() {
nativeAd = AdropNativeAd(
unitId: 'YOUR_UNIT_ID',
useCustomClick: true,
listener: AdropNativeListener(
onAdReceived: (ad) {
// HTMLクリエイティブをロード
if (ad.properties.creative != null) {
webViewController.loadHtmlString(ad.properties.creative!);
}
setState(() {
isLoaded = true;
});
},
),
);
nativeAd?.load();
}
@override
Widget build(BuildContext context) {
if (!isLoaded) return const SizedBox.shrink();
return AdropNativeAdView(
ad: nativeAd,
child: Container(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// プロフィール
Row(
children: [
if (nativeAd?.properties.profile?.displayLogo != null)
Image.network(
nativeAd!.properties.profile!.displayLogo!,
width: 24,
height: 24,
),
const SizedBox(width: 8),
Text(nativeAd?.properties.profile?.displayName ?? ''),
],
),
const SizedBox(height: 8),
// ヘッドライン
if (nativeAd?.properties.headline != null)
Text(
nativeAd!.properties.headline!,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
// HTMLクリエイティブ
SizedBox(
width: MediaQuery.of(context).size.width,
height: 300,
child: WebViewWidget(controller: webViewController),
),
// CTAボタン
if (nativeAd?.properties.callToAction != null)
Padding(
padding: const EdgeInsets.only(top: 8),
child: ElevatedButton(
onPressed: () {},
child: Text(nativeAd!.properties.callToAction!),
),
),
],
),
),
);
}
}
HTMLクリエイティブを使用するには、webview_flutterパッケージを追加する必要があります。flutter pub add webview_flutter
バックフィル広告の処理
ネイティブ広告がバックフィル広告の場合、isBackfilledプロパティで確認して処理できます。
Widget _buildCreativeView() {
if (nativeAd?.isBackfilled == true) {
// バックフィル広告: 画像アセットを使用
return Image.network(
nativeAd?.properties.asset ?? '',
width: double.infinity,
fit: BoxFit.cover,
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) return child;
return const Center(child: CircularProgressIndicator());
},
errorBuilder: (context, error, stackTrace) {
return const Icon(Icons.error);
},
);
} else if (nativeAd?.properties.creative != null) {
// 通常広告: HTMLクリエイティブを使用
return SizedBox(
width: double.infinity,
height: 300,
child: WebViewWidget(controller: webViewController),
);
} else {
return const SizedBox.shrink();
}
}
追加フィールドの使用
媒体社が定義した追加フィールドはextraマップからアクセスできます。
onAdReceived: (ad) {
// 追加フィールドにアクセス
final customField = ad.properties.extra['customFieldKey'];
if (customField != null) {
debugPrint('カスタムフィールド: $customField');
}
setState(() {
isLoaded = true;
});
}
エラー処理
バックフィル関連エラー
バックフィル広告が設定されている場合、直接広告とバックフィル広告の両方がない場合はbackfillNoFillエラーコードが返されます。
onAdFailedToReceive: (ad, errorCode) {
if (errorCode == AdropErrorCode.backfillNoFill) {
debugPrint('バックフィル広告もありません');
}
}
一般的なエラー処理
class _NativeAdState extends State<NativeAdWidget> {
bool isLoaded = false;
AdropErrorCode? errorCode;
AdropNativeAd? nativeAd;
@override
void initState() {
super.initState();
nativeAd = AdropNativeAd(
unitId: 'YOUR_UNIT_ID',
listener: AdropNativeListener(
onAdReceived: (ad) {
setState(() {
isLoaded = true;
errorCode = null;
});
},
onAdFailedToReceive: (ad, error) {
// バックフィル関連エラー処理
if (error == AdropErrorCode.backfillNoFill) {
debugPrint('バックフィル広告もありません');
}
setState(() {
isLoaded = false;
errorCode = error;
});
},
),
);
nativeAd?.load();
}
@override
Widget build(BuildContext context) {
if (isLoaded) {
return _buildNativeAdView();
} else if (errorCode != null) {
return Text('広告ロード失敗: ${errorCode?.code}');
} else {
return const SizedBox.shrink();
}
}
Widget _buildNativeAdView() {
// ネイティブ広告UIの構成
return AdropNativeAdView(
ad: nativeAd,
child: Container(
// ...
),
);
}
}
ベストプラクティス
1. 広告の再生成
新しい広告をロードするには、新しいAdropNativeAdインスタンスを生成します。
void resetAd() {
setState(() {
isLoaded = false;
});
nativeAd = AdropNativeAd(
unitId: 'YOUR_UNIT_ID',
listener: AdropNativeListener(
onAdReceived: (ad) {
setState(() {
isLoaded = true;
});
},
),
);
nativeAd?.load();
}
2. 条件付きレンダリング
広告がロードされるまで適切なプレースホルダーを表示します。
Widget buildNativeAd() {
if (isLoaded && nativeAd != null) {
return _buildNativeAdView();
} else if (isLoading) {
return const SizedBox(
height: 200,
child: Center(child: CircularProgressIndicator()),
);
} else {
return const SizedBox.shrink();
}
}
3. レスポンシブレイアウト
様々な画面サイズに対応できるようにレイアウトを構成します。
Widget _buildNativeAdView() {
return AdropNativeAdView(
ad: nativeAd,
child: LayoutBuilder(
builder: (context, constraints) {
return Container(
width: constraints.maxWidth,
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 広告コンテンツ
],
),
);
},
),
);
}
4. 広告プロパティのnullチェック
ネイティブ広告プロパティはnullの可能性があるため、常に確認します。
Widget _buildHeadline() {
final headline = nativeAd?.properties.headline;
if (headline == null || headline.isEmpty) {
return const SizedBox.shrink();
}
return Text(
headline,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
);
}
次のステップ
インタースティシャル広告
画面全体を覆うインタースティシャル広告を実装する
ポップアップ広告
ポップアップ形式で表示される広告を実装する
リファレンス
タイプ、メソッド、エラーコードを参照する