fix(ad): 높이에 따라 템플릿/최소높이 자동 조정

This commit is contained in:
JiWoong Sul
2025-12-05 16:06:30 +09:00
parent 887f1ad6fe
commit 753f578504

View File

@@ -19,7 +19,7 @@ class NativeAdPlaceholder extends StatefulWidget {
const NativeAdPlaceholder({ const NativeAdPlaceholder({
super.key, super.key,
this.margin, this.margin,
this.height = 360, this.height = 200,
this.refreshInterval = const Duration(minutes: 2), this.refreshInterval = const Duration(minutes: 2),
this.enabled = true, this.enabled = true,
}); });
@@ -55,6 +55,14 @@ class _NativeAdPlaceholderState extends State<NativeAdPlaceholder> {
return; return;
} }
final oldType = _templateTypeForHeight(oldWidget.height);
final newType = _templateTypeForHeight(widget.height);
if (oldType != newType) {
_loadAd();
return;
}
if (!oldWidget.enabled && widget.enabled) { if (!oldWidget.enabled && widget.enabled) {
_loadAd(); _loadAd();
return; return;
@@ -92,10 +100,11 @@ class _NativeAdPlaceholderState extends State<NativeAdPlaceholder> {
}); });
final adUnitId = AdHelper.nativeAdUnitId; final adUnitId = AdHelper.nativeAdUnitId;
final templateType = _templateTypeForHeight(widget.height);
_nativeAd = NativeAd( _nativeAd = NativeAd(
adUnitId: adUnitId, adUnitId: adUnitId,
request: const AdRequest(), request: const AdRequest(),
nativeTemplateStyle: _buildTemplateStyle(), nativeTemplateStyle: _buildTemplateStyle(templateType),
listener: NativeAdListener( listener: NativeAdListener(
onAdLoaded: (ad) { onAdLoaded: (ad) {
if (!mounted) { if (!mounted) {
@@ -131,10 +140,10 @@ class _NativeAdPlaceholderState extends State<NativeAdPlaceholder> {
_refreshTimer = Timer(delay, _loadAd); _refreshTimer = Timer(delay, _loadAd);
} }
NativeTemplateStyle _buildTemplateStyle() { NativeTemplateStyle _buildTemplateStyle(TemplateType templateType) {
final isDark = Theme.of(context).brightness == Brightness.dark; final isDark = Theme.of(context).brightness == Brightness.dark;
return NativeTemplateStyle( return NativeTemplateStyle(
templateType: TemplateType.medium, templateType: templateType,
mainBackgroundColor: isDark ? AppColors.darkSurface : Colors.white, mainBackgroundColor: isDark ? AppColors.darkSurface : Colors.white,
cornerRadius: 0, cornerRadius: 0,
callToActionTextStyle: NativeTemplateTextStyle( callToActionTextStyle: NativeTemplateTextStyle(
@@ -218,15 +227,25 @@ class _NativeAdPlaceholderState extends State<NativeAdPlaceholder> {
} }
double _resolveContainerHeight() { double _resolveContainerHeight() {
final platformMinHeight = switch (defaultTargetPlatform) { final templateType = _templateTypeForHeight(widget.height);
final minHeight = _templateMinHeight(templateType);
return max(widget.height, minHeight);
}
TemplateType _templateTypeForHeight(double height) {
// Medium 템플릿은 SDK 기본 레이아웃이 커서, 높이가 낮을 경우 Small로 대체해 잘림을 방지한다.
return height < 320 ? TemplateType.small : TemplateType.medium;
}
double _templateMinHeight(TemplateType type) {
if (type == TemplateType.small) {
return 120;
}
return switch (defaultTargetPlatform) {
TargetPlatform.iOS => 402.0, TargetPlatform.iOS => 402.0,
TargetPlatform.android => 350.0, TargetPlatform.android => 350.0,
_ => 320.0, _ => 320.0,
}; };
// 네이티브 템플릿(Medium) 기본 레이아웃이 플랫폼별로 350~402dp를 요구해
// 호출자가 지정한 높이보다 작을 경우 클리핑을 막기 위해 최소 높이를 강제한다.
return max(widget.height, platformMinHeight);
} }
BoxDecoration _decoration(bool isDark) { BoxDecoration _decoration(bool isDark) {