Как показано на изображении рекламный баннер admob обрезан или растянут.
Если я использую AdSize.banner, виджет не занимает всю ширину, но показывает рекламу правильно. Если я использую полный баннер, реклама растягивается.
Как сделать так, чтобы баннер помещался на всю ширину экрана и правильно отображал содержимое (без обрезания или растяжения)?
class _AdBannerState extends State<AdBanner> {
BannerAd? _inlineAdaptiveAd;
bool _isLoaded = false;
AdSize? _finalSize;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_loadAd();
}
void _loadAd() async {
await _inlineAdaptiveAd?.dispose();
setState(() {
_inlineAdaptiveAd = null;
_isLoaded = false;
});
// Get an inline adaptive size for the current orientation.
AdSize size = AdSize.fullBanner;
_inlineAdaptiveAd = BannerAd(
adUnitId: AdHelper.bannerAdUnitId,
size: size,
request: const AdRequest(),
listener: BannerAdListener(
onAdLoaded: (Ad ad) async {
debugPrint('Inline adaptive banner loaded: ${ad.responseInfo}');
// After the ad is loaded, get the platform ad size and use it to
// update the height of the container. This is necessary because the
// height can change after the ad is loaded.
BannerAd bannerAd = (ad as BannerAd);
_finalSize = await bannerAd.getPlatformAdSize();
// if (size == null) {
// debugPrint(
// 'Error: getPlatformAdSize() returned null for $bannerAd');
// return;
// }
setState(() {
_inlineAdaptiveAd = bannerAd;
_isLoaded = true;
});
},
onAdFailedToLoad: (Ad ad, LoadAdError error) {
debugPrint('Inline adaptive banner failedToLoad: $error');
ad.dispose();
},
),
);
await _inlineAdaptiveAd!.load();
}
@override
Widget build(BuildContext context) {
return (_inlineAdaptiveAd != null && _isLoaded && _finalSize != null)
? Expanded(
child: SizedBox(
width: _finalSize!.width.toDouble(),
height: _finalSize!.height.toDouble(),
child: AdWidget(
ad: _inlineAdaptiveAd!,
)))
: const SizedBox(
width: 0,
height: 0,
);
}
@override
void dispose() {
_inlineAdaptiveAd?.dispose();
super.dispose();
}
}
Чтобы сделать его отзывчивым,
Пожалуйста, используйте MethodChannel для вызова любого нативного метода java/kotlin, написанного как часть нативного кода Android, который можно вызвать из вашего .dart файла.
Пример папки ресурсов: Официальный пример Flutter
Пример канала метода: Пример официального канала метода Flutter
Вам необходимо самостоятельно создать указанные ниже папки и файлы внутри папки android/app/src/main/res, установить эти значения самостоятельно и соответствующим образом настроить.
Вариант 1: математически обрабатывать размеры _finalSize и AdWidget на основе значений из файлов ресурсов измерений dimens.xml с использованием имен папок Имен квалификаторов конфигурации
values-sw720dp 10.1” tablet 1280x800 mdpi
values-sw600dp 7.0” tablet 1024x600 mdpi
values-sw480dp 5.4” 480x854 mdpi
values-sw480dp 5.1” 480x800 mdpi
values-xxhdpi 5.5" 1080x1920 xxhdpi
values-xxxhdpi 5.5" 1440x2560 xxxhdpi
values-xhdpi 4.7” 1280x720 xhdpi
values-xhdpi 4.65” 720x1280 xhdpi
values-hdpi 4.0” 480x800 hdpi
values-hdpi 3.7” 480x854 hdpi
values-mdpi 3.2” 320x480 mdpi
values-ldpi 3.4” 240x432 ldpi
values-ldpi 3.3” 240x400 ldpi
values-ldpi 2.7” 240x320 ldpi
Определите дробь
<?xml version = "1.0" encoding = "utf-8"?>
<resources>
<fraction name = "division_factor_width">0.31</fraction>
<fraction name = "division_factor_height">0.41</fraction>
</resources>
Получить дробь
child: SizedBox(
width: _finalSize!.width.toDouble() / getResources().getFraction(R.dimen.division_factor_width, 1,1),
height: _finalSize!.height.toDouble() / getResources().getFraction(R.dimen.division_factor_height, 1,1),
child: AdWidget(
ad: _inlineAdaptiveAd!,
)))
Вариант 2: Прочитайте ограничения в руководстве Понимание ограничений во флаттере
Вариант 3. Поместите SizedBox в другой макет, например линейный, и установите свойства макета так, чтобы центрировать поле, не растягивая его.
Вариант 4: создайте размерные объявления и вызовите AdHelper.bannerAdUnitId из values.xml значения.xml будут помещены в папки с несколькими размерами, например hdpildpi ... и т. д.
какой метод? получить ресурсы ()? ты о чем?
да еще и ресурс. XML
Пожалуйста, используйте MethodChanneldocs.flutter.dev/platform-integration/platform-channels для вызова любого нативного метода java/kotlin, написанного как часть нативного кода Android, который можно вызвать из вашего .dart файла.
все эти xml-файлы ресурсов принадлежат собственному коду Android, который находится внутри вашего проекта флаттера с двумя папками androidios, где написан исходный собственный код
Вам нужно создать эти папки и файлы внутри папки android/app/src/main/res самостоятельно, установить эти значения самостоятельно и соответствующим образом настроить.
Замените виджет Expanded на LayoutBuilder и рассчитайте максимальную доступную ширину (maxWidth) на основе ограничений, как показано ниже:
class _AdBannerState extends State<AdBanner> {
BannerAd? _inlineAdaptiveAd;
bool _isLoaded = false;
double _adHeight = 0;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_loadAd();
}
void _loadAd() async {
await _inlineAdaptiveAd?.dispose();
setState(() {
_inlineAdaptiveAd = null;
_isLoaded = false;
});
// Get an inline adaptive size for the current orientation.
AdSize size = AdSize.fullBanner;
_inlineAdaptiveAd = BannerAd(
adUnitId: AdHelper.bannerAdUnitId,
size: size,
request: const AdRequest(),
listener: BannerAdListener(
onAdLoaded: (Ad ad) async {
debugPrint('Inline adaptive banner loaded: ${ad.responseInfo}');
setState(() {
_inlineAdaptiveAd = ad as BannerAd;
_isLoaded = true;
});
},
onAdFailedToLoad: (Ad ad, LoadAdError error) {
debugPrint('Inline adaptive banner failedToLoad: $error');
ad.dispose();
},
),
);
await _inlineAdaptiveAd!.load();
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
double maxWidth = constraints.maxWidth;
double maxHeight = maxWidth / _inlineAdaptiveAd!.size.width * _inlineAdaptiveAd!.size.height;
_adHeight = maxHeight;
return (_inlineAdaptiveAd != null && _isLoaded)
? SizedBox(
width: maxWidth,
height: _adHeight,
child: AdWidget(ad: _inlineAdaptiveAd!),
)
: SizedBox(
width: 0,
height: 0,
);
},
);
}
@override
void dispose() {
_inlineAdaptiveAd?.dispose();
super.dispose();
}
}
Я надеюсь, что это сработает для вас.
это все еще отрезать содержание.
Это видимо известная проблема. Отслеживается разработчиками. Еще не решено.
Обходной путь можно найти здесь. Не идеально.
https://github.com/googleads/googleads-mobile-flutter/issues/261#issuecomment-1293001373
Если я использую виджет AdSize.banner не занимает всю ширину, а показывает реклама правильно. Если я использую полный баннер, реклама растягивается.
Это потому что:
AdSize.banner Фактический размер 320x50.AdSize.fullBanner Фактический размер 468x60.Имейте в виду, что эти размеры фиксированы независимо от фактического размера экрана устройства. Чтобы уточнить, кажется, что ширина экрана эмулятора, которую вы используете, меньше 468 и больше 320.
Поэтому вам необходимо указать нестандартный размер в виде AdSize. Вместо объявления size и _finalSize как
AdSize size = AdSize.fullBanner;
_finalSize = const AdSize(height: 40, width: 320);
они могут быть чем-то вроде
// use it directly in the BannerAd creation
AdSize size = AdSize(
width: MediaQuery.of(context).size.width.toInt(),
height: 40,
);
// ...
// then let _finalSize be the same size for later use (in the build method)
_finalSize = size;
На данный момент я бы предположил, что нет необходимости оборачивать SizedBox в метод build с помощью Expanded.
Кроме того, вот совет:
Использовать
SizedBox.shrink();
вместо
const SizedBox(
width: 0,
height: 0,
);
Используйте эту линию
size: AdSize.banner
или
AdSize size = AdSize.banner;
Это не применимо к Flutter, ни один из методов не существует.