Перейти к основному содержимому
Версия: 3.3.2

Нативная реклама

Нативная реклама - это гибкий вид рекламы. Вы можете адаптировать показ к своему пользовательскому интерфейсу, подготовив шаблон.

к сведению

Appodeal предоставляет 4 варианта реализации макета нативной рекламы 3 шаблона + ваша кастомная реализация Все они наследуются от одного и того же класса NativeAdView.

NativeAdView состоит из следующих компонентов:

  1. NativeIconView - Иконка нативной рекламы.
  2. AdAttributionView - Индикатор рекламы. Это TextView с меткой "Ad".
  3. TitleVIew - Заголовок нативной рекламы.
  4. DescriptionView - Текстовый вид описания нативной рекламы.
  5. RatingBarView - Рейтинг приложения в диапазоне [0-5].
  6. NativeMediaView - Медиаконтент нативной рекламы.
  7. CallToActionView - Кнопка для клика.
  8. AdChoiceView - Специальная иконка объявления, предоставляемая рекламной сетью.
  • Шаблоны: Для их отображения достаточно сделать следующее:
  1. Создайте программно или в файле xml разметки один из классов View шаблонов;

Классы шаблонов нативной рекламы:.

  • NativeAdViewNewsFeed:

  • NativeAdViewAppWall:

  • NativeAdViewContentStream:

NativeAdView для кастомной реализации:

Для его отображения достаточно сделать следующее:

  1. Создайте класс NativeAdVIew программно или в xml файле разметки
  2. Внутри созданного NativeAdVIew расположите все View/IconView/MediaView, необходимые для отображения в любом удобном для вас стиле
  3. Привяжите программно или в файле макета все необходимые View/IconView/MediaView.

Вид нативной рекламы в кастомной реализации:

  • NativeAdView.

Вы можете использовать наше демо приложение в качестве примера по интеграции.

Демо приложение

Руководство по интеграции

  1. Создайте программно или в файле xml разметки один из классов View шаблонов:
<com.appodeal.ads.nativead.NativeAdViewNewsFeed
android:id="@+id/native_news_feed"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<com.appodeal.ads.nativead.NativeAdViewAppWall
android:id="@+id/native_app_wall"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<com.appodeal.ads.nativead.NativeAdViewContentStream
android:id="@+id/native_content_stream"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
  1. Получите экземпляр представления из макета ИЛИ добавьте программно созданный шаблон ViewTemplate в иерархию View:
val newsFeedView = findViewById<NativeAdViewNewsFeed>(R.id.native_news_feed);
val appWallView = findViewById<NativeAdViewAppWall>(R.id.native_app_wall);
val contentStreamView = findViewById<NativeAdViewContentStream>(R.id.native_content_stream);
NativeAdViewNewsFeed newsFeedView = findViewById(R.id.native_news_feed);
NativeAdViewAppWall appWallView = findViewById(R.id.native_app_wall);
NativeAdViewContentStream contentStreamView = findViewById(R.id.native_content_stream);
  1. Когда NativeAd будет загружен, просто зарегистрируйте его:
if (Appodeal.isLoaded(Appodeal.NATIVE)) { 
newsFeedView.registerView(Appodeal.getNativeAdCount(1))
}
  1. Когда показ завершен и вы больше не планируете использовать NativeAdView, необходимо вызвать метод destroy:
nativeAdView.destroy()

Проверка, загружена ли реклама

Чтобы проверить, загружен ли хотя бы 1 экземпляр NativeAd, используйте метод:

Appodeal.isLoaded(Appodeal.NATIVE)

Чтобы узнать, сколько экземпляров NativeAd загружено, используйте метод:

val nativeAmount = Appodeal.getAvailableNativeAdsCount()
примечание

По умолчанию Appodeal SDK с включенной функцией AutoCahce загружает по 2 экземпляра NativeAd.

подсказка

Мы рекомендуем всегда проверять, доступно ли объявление, прежде чем пытаться его показать.

Получить загруженную рекламу

Чтобы получить загруженную нативную рекламу, воспользуйтесь следующим методом:

val nativeAds: List<NativeAd> = Appodeal.getNativeAds(amount)
осторожно

После получения рекламы она удаляется из нашего кэша SDK.

Отображение

Для отображения NativeAd необходимо вызвать следующий код:

NativeAdView.registerView(nativeAd: NativeAd)
осторожно

SDK не может показывать рекламу без подключения к сети!

NativeAdView.registerView() возвращает значение boolean, указывающее, был ли вызов метода show передан соответствующему SDK.

к сведению

Перед вызовом метода registerView(nativeAd), NativeAdView находится в состоянии visibility == GONE. После вызова состояние автоматически изменится на visibility == VISIBLE.

Вам не нужно менять состояние видимости, Appodeal SDK делает это автоматически.

После вызова destroy() состояние автоматически изменится на visibility == GONE.

подсказка

NativeAdView и его наследники имеют встроенный атрибут tools:visibility="visible", поэтому представление будет отображаться в разметке IDE во время разработки.

Плейсменты

Appodeal SDK позволяет маркировать каждый показ различными плейсментами. Чтобы использовать плейсмент, необходимо создать его в Appodeal Dashboard. Узнайте больше о плейсментах.

Чтобы показать рекламу с плейсментом, необходимо вызвать метод show:

NativeAdView.registerView(nativeAd: NativeAd, yourPlacementName: String)
к сведению

Если загруженное объявление не может быть показано для конкретного размещения, то ничего показано не будет.

Если автоматическое кэширование включено, sdk начнет загружать очередную рекламу, что может повлиять на display rate. Чтобы сохранить загруженную рекламу для дальнейшего использования (например, для другого плейсмента), проверьте, может ли оно быть показано до вызова метода show:

if (NativeAd.canShow(context: Context, yourPlacementName: String)){
NativeAdView.registerView(nativeAd: NativeAd, yourPlacementName: String)
}

Для каждого плейсмента можно настроить свою логику показа.

к сведению

Если у вас нет плейсментов, или вы вызываете NativeAdView.registerView с несуществующим плейсментом, показ будет помече как плейсмент 'по умолчанию' и будут применены его настройки.

примечание

Настройки плейсмента влияют ТОЛЬКО на показ рекламы, но не на загрузку или кэширование.

Прекращение трекинга показа

Для прекращение трекинга показа нативной рекламы с зарегистрированной в данный момент NativeAdView используйте метод:

NativeAdView.unregisterView()
примечание

Метод UnregisterView не скрывает NativeAdView. Он приостанавливает отслеживание отображения нативной рекламы.

подсказка

UnregisterView имеет смысл использовать, например, если NativeAdView находится за пределами экрана во время прокрутки списка или временно перекрывается другим View/Fragment/Activity.

Уничтожение нативной рекламы

Чтобы уничтожить NativeAdView и выполнить очистку ресурсов, а также скрыть ваш View, используйте метод:

NativeAdView.destroy()
к сведению

Этот метод следует вызывать, когда нативная реклама больше не нужна.

Кроме того, при вызове destroy() срабатывает логика unregisterView.

Методы обратного вызова

Appodeal.setNativeCallbacks(object : NativeCallbacks {
override fun onNativeLoaded() {
// Срабатывает когда реклама была загружена
}
override fun onNativeFailedToLoad() {
// Срабатывает при невозможности загрузки рекламы в данный момент
}
override fun onNativeShown(nativeAd: NativeAd) {
// Срабатывает при отображении нативной рекламы
}
override fun onNativeShowFailed(nativeAd: NativeAd) {
// Срабатывает при ошибке показа нативной рекламы
}
override fun onNativeClicked(nativeAd: NativeAd) {
// Срабатыввает при клике на нативную рекламу
}
override fun onNativeExpired() {
// Срабатывает когда нативная рекламы была просрочена
}
})
к сведению

Все методы обратного вызова вызываются в главном потоке

Ручное кеширование

Чтобы отключить автоматическое кэширование нативной рекламы, используйте приведенный ниже код перед инициализацией SDK:

Appodeal.setAutoCache(Appodeal.NATIVE, false)

Узнайте больше у ручном кешировании в нашем FAQ.

Кеширование

Для загрузки нативной рекламы используйте метод:

Appodeal.cache(this, Appodeal.NATIVE)

Для загрузки несколькиъ экземпляров нативной рекламы используйте метод:

Appodeal.cache(this, Appodeal.NATIVE, 3)
примечание

Вы можете запросить максимум 5 NativeAd.

Количество кэшированных объявлений не гарантируется и может быть меньше запрошенного.

Проверка инициализации рекламы

Проверить, инициализирована ли нативная реклама, можно с помощью метода:

Appodeal.isInitialized(Appodeal.NATIVE)

Возавращает true, если нативная реклама была проинициализирована.

Провека, включен ли автокэш

Чтобы проверить, включен ли автокэш для нативной рекламы, можно воспользоваться методом:

Appodeal.isAutoCacheEnabled(Appodeal.NATIVE)

Возвращает true, если автокеш включен для нативной рекламы.

Получение прогнозируемого eCPM

Чтобы получить прогнозируемый eCPM из следующего блока в очереди на опрос, используйте метод:

NativeAd.predictedEcpm

Конфигурация

Установка предпочтительного типа медиаконтента

Вы можете указать Appodeal SDK предпочтительный тип контента для NativeAd. Для этого используйте метод:

// будут загружаться как статические изображения, так и видео контент
Appodeal.setPreferredNativeContentType(NativeMediaViewContentType.Auto)
// будет загружаться только статические изображения
Appodeal.setPreferredNativeContentType(NativeMediaViewContentType.NoVideo)
// будет загружаться только видео контент
Appodeal.setPreferredNativeContentType(NativeMediaViewContentType.Video)
к сведению

Установка типа видео не гарантирует, что оно будет загружено, а лишь указывает предпочтительный тип.

Проверить, содержит ли загружаемая реклама видео, можно с помощью метода:

NativeAd.containsVideo()

Возвращает true, если NativeAd содержит видео.

Используйте этот метод для получения предпочтительного типа содержимого:

Appodeal.getPreferredNativeContentType()
примечание

Действует только на содержимое внутри NativeMediaView. Поэтому имеет смысл использовать его только в случае случае шаблона NativeAdViewContentStream или собственной пользовательской реализации NativeAdView.

Контент для NativeIconView всегда представляет собой статическое изображение

указание позиции adChoice

Вы можете задать позицию в одном из углов NativeAdView:

app:adChoicePosition="end_top"
к сведению

В качестве Position можно указать один из 4 вариантов:

START_TOP - совпадает с левым верхним углом NativeAdView;

START_BOTTOM - совпадает с левым нижним углом NativeAdView;

END_TOP - совпадает с правым верхним углом NativeAdView;

END_BOTTOM - совпадает с правым нижним углом NativeAdView.

Настройка AdAttributionView

Цвет текста и цвет фона для AdAttributionView можно задать в NativeAdView:

app:adAttributionBackgroundColor="@color/red"
app:adAttributionTextColor="@color/black"
к сведению

Цвет должен иметь формат ColorInt. См. раздел android.graphics.Color.

примечание

Для пользовательского NativeAdView вы можете сделать то же самое через вашу xml-разметку, используя атрибуты android:textColor и android:background для adAttribution TextView.

Работа со списками

Чтобы использовать NativeAd в RecyclerView, можно воспользоваться следующим примером:

  1. Создайте объект ListItem, который будет служить для определения itemViewType в RecyclerView.ListAdapter
sealed interface ListItem {
fun getItemId(): Int

class NativeAdItem(val getNativeAd: () -> NativeAd?) : ListItem {
override fun getItemId() = NATIVE_AD_ITEM

companion object {
const val NATIVE_AD_ITEM = 3
}
}

data class YourDataItem(val userData: Int) : ListItem {
override fun getItemId() = USER_ITEM

companion object {
const val USER_ITEM = 2
}
}
}
  1. Создать объект DiffUtil.ItemCallback<ListItem>, который будет сообщать ListAdapter различия между элементами
internal class DiffUtils : DiffUtil.ItemCallback<ListItem>() {
override fun areItemsTheSame(oldItem: ListItem, newItem: ListItem) =
oldItem.getItemId() == newItem.getItemId()

override fun areContentsTheSame(oldItem: ListItem, newItem: ListItem) =
oldItem.hashCode() == newItem.hashCode()
}
  1. Создайте объект ListAdapter, который будет являться адаптером для RecyclerView:
class NativeListAdapter : ListAdapter<ListItem, ListHolder>(DiffUtils()) {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListHolder {
return when (viewType) {
NATIVE_AD_ITEM -> { DynamicAdViewHolder(NativeAdViewContentStream(parent.context)) }
else -> {
YourViewHolder(
YourDataItemBinding.inflate(LayoutInflater.from(parent.context),
parent,
false
))
}
}
}

override fun onBindViewHolder(holder: ListHolder, position: Int) {
when (val item = getItem(position)) {
is ListItem.YourDataItem -> (holder as YourViewHolder).bind(item)
is ListItem.NativeAdItem -> (holder as DynamicAdViewHolder).bind(item)
}
}

override fun getItemViewType(position: Int): Int {
return when (currentList[position]) {
is ListItem.YourDataItem -> USER_ITEM
is ListItem.NativeAdItem -> NATIVE_AD_ITEM
}
}

sealed class ListHolder(root: View) : RecyclerView.ViewHolder(root) {
class YourViewHolder(private val binding: YourDataItemBinding) : ListHolder(binding.root) {
fun bind(item: ListItem.YourDataItem) {
binding.root.text = item.userData.toString()
}
}

class DynamicAdViewHolder(itemView: View) : ListHolder(itemView) {
fun bind(item: ListItem.NativeAdItem) {
val nativeAd = item.getNativeAd.invoke()
if (nativeAd != null) {
(itemView as NativeAdView).registerView(nativeAd)
}
}
}
}
}
к сведению

NATIVE_AD_ITEM - NativeAdItem.NATIVE_AD_ITEM

  1. В качестве Activity/Fragment будем использовать разметку:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:attr/colorBackground">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

</FrameLayout>

Мы будем использовать этот пример в качестве разметки YourDataItem:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:textSize="64sp"
tools:text="1" />
  1. В вашем Activity/Fragment, добавьте следующий код:
class NativeActivity : AppCompatActivity() {

private val getNativeAd: () -> NativeAd? = { Appodeal.getNativeAds(1).firstOrNull() }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = ActivityNativeBinding.inflate(layoutInflater)
setContentView(binding.root)

val nativeListAdapter = NativeListAdapter()
binding.recyclerView.adapter = nativeListAdapter

setUpAppodealSDK()
}

private fun setUpAppodealSDK() {
Appodeal.setLogLevel(LogLevel.verbose)
Appodeal.setTesting(true)
Appodeal.initialize(this, APPODEAL_APP_KEY, Appodeal.NATIVE) { errors ->
val initResult = if (errors.isNullOrEmpty()) "successfully" else "with ${errors.size} errors"
Log.d("TAG", "onInitializationFinished: $initResult")
}
}

private fun obtainData(nativeListAdapter: NativeListAdapter) {
val yourDataItems = generateYourData()
nativeListAdapter.submitList(yourDataItems.addNativeAdItems())
}

private fun List<ListItem>.addNativeAdItems() =
this.foldIndexed(
initial = listOf(),
operation = { index: Int, acc: List<ListItem>, yourDataItem: ListItem ->
val shouldAdd = index % STEPS == 0 && index != 0
if (shouldAdd) {
acc + createNativeAdItem() + yourDataItem
} else {
acc + yourDataItem
}
}
)

private fun generateYourData(): List<ListItem> =
(1..USER_DATA_SIZE).toList().map { ListItem.YourDataItem(userData = it) }

private fun createNativeAdItem(): ListItem.NativeAdItem =
ListItem.NativeAdItem(getNativeAd = getNativeAd)
}
private const val USER_DATA_SIZE = 200
private const val STEPS = 5
к сведению

STEPS - шаг, через который будет устанавливаться NativeAd;

addNativeAdItems() - логика вставки NativeAd в список через определенное количество STEPS.

Готово! Когда вы захотите вставить нативные объявления в RecyclerView, просто вызовите метод obtainData().

Распространенные ошибки

  • Отсутствует adAttributionView

Большинство рекламных сетей требуют от издателей добавлять специальную метку к нативным объявлениям, чтобы пользователи не приняли их за контент. Поэтому всегда нужно следить за тем, чтобы нативная реклама в вашей разметке имели adAttributionView (например, "Ad") и значок AdChoices.

  • Отсутствие необходимых элементов нативной рекламы.

Каждое нативное объявление должно содержать:

  • titleView TextView;

  • callToActionView Button;

  • adAttribution TextView;

  • NativeIconView или NativeMedaiaView.

  • Изменение элементов нативной рекламы.

Рекламодатели ожидают, что их объявления будут отображаться четко и без каких-либо изменений. Вы можете масштабировать кнопки и изображения, но не следует их обрезать, закрывать или искажать.

  • Наложение элементов нативной рекламы друг на друга.

Убедитесь, что все элементы нативного объявления видны и не накладываются друг на друга.

Требования к нативным объявлениям:

  • Все поля нативной рекламы, отмеченные как обязательные, должны быть отображены.
  • Размер изображений может быть изменен в соответствии с размерами рекламного пространства, но не
  • должен быть значительно искажен или обрезаны.

Проверка отображения

Вы всегда можете проверить в логах, был ли отслежен показ и видно ли вашу рекламу.

В случае успешного показа вы увидите лог Native [Notify Shown].

Appodeal  com.example.app  D Native [Notify Shown]