در لیستهای طولانی یا نامحدود اسکرول، مانند فیدهای خبری یا فیدهای اجتماعی، ایجاد یک بنر تبلیغاتی برای هر موقعیت آیتم میتواند منجر به مصرف زیاد حافظه و تأخیر رابط کاربری شود. برای بهبود عملکرد، از بازیافت بنر برای حفظ یک حافظه پنهان کوچک و ثابت از نمونههای BannerAd استفاده کنید و با اسکرول کاربر، از تبلیغات خارج از صفحه دوباره استفاده کنید.
این صفحه به مواردی مانند تعیین اندازه حافظه پنهان تبلیغات، بررسی خارج از صفحه بودن یک نمونه BannerAd و اختصاص مجدد تبلیغات ذخیره شده به موقعیتهای لیست میپردازد.
تصویر زیر نشان میدهد که چگونه یک بنر تبلیغاتی خارج از صفحه، با اسکرول کردن کاربر، به حافظه پنهان (cache) برمیگردد و در یک موقعیت فهرست، دوباره استفاده میشود:

پیشنیازها
قبل از ادامه، از بنرهای پیمایشی تطبیقی درونخطی استفاده کنید .
پیگیری موقعیتهای تعیینشده در فهرست
همزمان با اسکرول کردن کاربر، قابلیت بازیافت بنر تعداد محدودی از نمونههای BannerAd را در حافظه نگه میدارد و این نمونهها را بین موقعیتهای لیست جابجا میکند.
برای اینکه بدانید از کدام تبلیغ دوباره استفاده کنید، بررسی کنید که هر تبلیغ در حافظه پنهان کدام جایگاه را در لیست اشغال میکند.
حالت زیر را در ویجت خود حفظ کنید:
- یک حافظه پنهان با اندازه ثابت از نمونههای
BannerAd. اندازهای که شما برای حافظه پنهان تنظیم میکنید، حداکثر تعداد تبلیغاتی است که به طور همزمان در حافظه نگهداری میشوند. - فاصله زمانی نمایش تبلیغ که مشخص میکند یک تبلیغ چند بار در لیست نمایش داده میشود.
- یک کلاس
Mapموقعیت که هر نمونهBannerAdرا با موقعیتی که آن نمونه در لیست اشغال میکند مرتبط میکند. وقتی یک تبلیغ را بازیافت میکنید، ورودی این کلاسMapرا بهروزرسانی کنید تا به آخرین موقعیت اشاره کند. - یک کلاس
Mapاندازه که شیءAdSizeمربوط به پلتفرم را برای هر تبلیغ بارگذاری شده ذخیره میکند. پس از بارگذاری تبلیغ، ارتفاع بنر تطبیقی درونخطی مشخص میشود.
مثال زیر موقعیتهای اختصاص داده شده به هر تبلیغ در حافظه پنهان (cache) را در لیست ردیابی میکند:
// Maximum number of banner ad instances kept in the cache.
static const int _cacheSize = 8;
// Spacing between banner ads. For example, index 0, 6, 12, and so on
// display ads.
static const int _adInterval = 6;
// The cache of allocated BannerAd instances.
final List<BannerAd> _banners = [];
// Maps each BannerAd instance to its currently assigned list item position.
final Map<BannerAd, int> _bannerPositions = {};
// Stores the platform-resolved size of each loaded banner ad.
final Map<BannerAd, AdSize> _bannerSizes = {};
اندازه حافظه پنهان را انتخاب کنید
حافظه پنهان را بزرگتر از حداکثر تعداد تبلیغاتی که میتوانند همزمان روی صفحه نمایش داده شوند، تنظیم کنید. اگر حافظه پنهان کوچکتر از این اندازه باشد، تبلیغی که برای بازیافت انتخاب شده است، اغلب هنوز قابل مشاهده است و برنامه شما به جای استفاده مجدد از تبلیغات، تبلیغات اضافی را اختصاص میدهد.
برای انتخاب سایز، مراحل زیر را انجام دهید:
- با تقسیم ارتفاع نمایشگر بر ارتفاع یک بازه تبلیغ، تخمین بزنید که چند تبلیغ به طور همزمان روی صفحه نمایش جا میشوند.
- برای تبلیغاتی که هنگام اسکرول سریع هنوز جدا میشوند، فضا اضافه کنید.
- اگر میبینید که تبلیغات انتخابشده برای بازیافت هنوز روی صفحه هستند، اندازه حافظه پنهان را افزایش دهید.
مثال موجود در این صفحه، هر شش ردیف یک تبلیغ نمایش میدهد و از یک حافظه پنهان هشتتایی استفاده میکند. این مثال، فضایی را برای چند تبلیغی که همزمان روی صفحه نمایش داده میشوند، باقی میگذارد.
بررسی کنید که آیا یک تبلیغ روی صفحه نمایش داده میشود یا خیر
تمام کلاسهای Google Mobile Ads Flutter Plugin که نماهای پلتفرم را رندر میکنند، کلاس AdWithView را پیادهسازی میکنند و یک گیرنده isMounted ارائه میدهند. قبل از اختصاص مجدد یک تبلیغ ذخیره شده به یک موقعیت لیست، گیرنده isMounted را بررسی کنید تا تأیید شود که تبلیغ از صفحه خارج شده و برای استفاده مجدد ایمن است.
بازیابی و بازیافت یک بنر تبلیغاتی
وقتی لیست برای یک موقعیت مشخص درخواست بنر میکند، موارد زیر را انجام دهید:
- در صورت وجود، از تبلیغی که قبلاً به آن موقعیت اختصاص داده شده است، دوباره استفاده کنید.
- اگر حافظه پنهان پر نیست، درخواست تبلیغ دهید.
- اگر حافظه پنهان پر است، یک تبلیغ ذخیره شده را انتخاب کنید و قبل از اختصاص مجدد تبلیغ، بررسی کنید که مقدار گیرنده
isMountedبرابر باfalseباشد. - وقتی ویجت از درخت ویجت حذف میشود، متد
dispose()را روی هر تبلیغ موجود در حافظه پنهان فراخوانی کنید.
مثال زیر یک بنر تبلیغاتی را بازیابی و بازیافت میکند:
BannerAd _getRecycledBannerAd(BuildContext context, int bannerPosition) {
// 1. If an ad is already mapped to this position, reuse it.
final BannerAd? existingBanner = _bannerPositions.entries
.firstWhereOrNull((entry) => entry.value == bannerPosition)
?.key;
if (existingBanner != null) {
return existingBanner;
}
// 2. If the cache is not full, allocate a new ad instance.
if (_banners.length < _cacheSize) {
final BannerAd newBanner = _createBannerAd(context);
_banners.add(newBanner);
_bannerPositions[newBanner] = bannerPosition;
return newBanner;
}
// 3. Select an existing ad from the cache using modulo arithmetic.
final BannerAd targetBanner = _banners[bannerPosition % _cacheSize];
// 4. Verify the ad is detached from the screen before recycling.
if (targetBanner.isMounted) {
// If still on screen during fast scrolls, allocate a temporary instance.
return _createBannerAd(context);
} else {
// Safe to reuse: reassign to the new position.
_bannerPositions[targetBanner] = bannerPosition;
return targetBanner;
}
}
برای مثال کامل، به مثال Google Mobile Ads Flutter Plugin مراجعه کنید.