Отображение нативной рекламы в RecyclerView - PullRequest
1 голос
/ 10 июня 2019

Я работаю с RecyclerView. В котором я должен показать два элемента в GridLayout Manager и счетчик промежутков 2, чтобы показывать нативную рекламу с полной шириной. Кто-нибудь может мне помочь. Output coming like image 1

Actual Output I need like image 2

1 Ответ

0 голосов
/ 10 июня 2019

Я думаю, что нашел решение, которое может работать для вас.Я использую Kotlin здесь, но я уверен, что то же самое может быть достигнуто в Java.

Допущения

  • Вы используете GridLayoutManager
  • Вы хотите вставить«объявление» каждое количество элементов N.
  • Вы реализовали или у вас есть способы определить, какой ТИП данных вы показываете (иначе: вы надуваете разные «ViewHolders» на основе itemType.
  • У вас нет проблем с вставкой заполнителей в список неизменяемых данных, поэтому ваш адаптер RecyclerView не полон сумасшедшей логики, а также ваш GridLayout не должен быть пользовательским.

Как?

  • Менеджер макетов сетки, вычисляет макеты / меры в зависимости от количества «промежутков» (которые я мысленно называю столбцами, даже если это на самом деле не означает это).
  • Когда вы создаете GridLayoutManager, вы делаете это, предоставляя количество промежутков, которое указанная компоновка будет span (смеется?)
  • Можно изменить количество промежутков (?), которое будет отображаться span когда выложено в сетке.По умолчанию представления будут охватывать ОДИН промежуток (вполне достаточно, если уже span thingy ).

Достаточно слова "Span" ...

Скажитеу вас есть List<Thing> в качестве источника данных.У вас есть 0..n вещей .Указанный Thing имеет средства для идентификации по типу.ака: aThing.type.Представьте, что у вас есть два типа:

Обычный и AD.

enum Type { Normal, AD }

(например).

, так что вы можете сделать:

if (thing.type == Type.AD)

Теперь я предполагаю, что вы получаете список Thing из своего хранилища.

У вас есть разные варианты (я рассмотрю только один и оставлю другие в качестве упражнения для читателя, в первую очередь потому, что у меня не так много времени, а также потому, что каждое лучшее решение будет действительно зависеть от контекста. У меня не так много контекста здесь).Мое требование простое: сделать так, чтобы объявления охватывали всю сетку.

Простое решение включает в себя изменение списка результатов, которые дает вам репозиторий (заметьте, я не буду трогать данные репо, сделайте копию, используйте копию для вашего адаптера).

Так что когдаВы получаете свой список, вместо того, чтобы отправлять его непосредственно в адаптер , измените его:

(это псевдокод, предполагая, что listOfData - это данные, которые вы хотите показать, уже заполненныеКонечно)

var newList = ArrayList<Thing>()

for ((index, thing) in listOfData.withIndex()) {
    // if it's an Ad, insert one, and continue adding items
    if (index % 4 == 0) {
        newList.add(AdPlaceholder())
    } else {
        newList.add(thing)
    }
}

return newList

Таким образом, мы возвращаем newList на основе исходного списка (это просто способ сделать это, не единственный и, конечно, не самый лучший во всех контекстах, может быть многобольше, чем кажется на первый взгляд).

Что такое AdPlaceholder()?

Это просто специализированная «вещь» :) (см. ниже).

Теперь где-то в вашей деятельности/ Фрагмент, вы, вероятно, настроили свой рециклер-вид следующим образом: (опять же, псевдокод, но действительный Kotlin)

 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        layoutManager = GridLayoutManager(this, 2)
        mainRecyclerView.layoutManager = layoutManager
        mainRecyclerView.adapter = YourAdapter()

        // and somewhere you'll send data to this adapter...
        adapter.submitList(repository.getMyListOfThings())
  }

Это будет выглядеть как ваша начальная сетка.

Сначала я подумал, а что если мы создадим собственный LayoutManager, который «интеллектуален» в отношении того, когда показывать рекламу и еще много чего?

Но потом я обнаружил, что есть значение , которое интеллектуально отображается в GridLayoutManager (и работает):

spanSizeLookup: устанавливает источникчтобы получить число промежутков, занимаемых каждым элементом в адаптере.

Это именно то, что нам нужно, чтобы сказать сетке: эй, этот элемент занимает N промежутков, но этот другой элемент занимает Y.

Итак, я добавил это:

layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
    override fun getSpanSize(position: Int): Int {
        return when (adapter.getItemViewType(position)) {
            adapter.normalViewType -> 1
            adapter.adViewType -> 2
            else -> 1 //default
        }
    }
}

И вуаля!

Поскольку это очень много для обработки, я создал пример проекта это показывает это в действии.В ней есть ошибка, надеюсь, вы сможете ее обнаружить (и исправить!):)

Примечание. Я не использовал библиотеку загрузки AD, это ваше дело.Имейте в виду, что реклама обычно реализуется в виде веб-представлений и, следовательно, имеет тенденцию быть медленной, асинхронной и т. Д. Будьте готовы показать заполнители, когда реклама еще не загружена и т. Д. Это действительно будет зависеть от того, как вы реализуете эту сторону вещей, небо - этопредел.Это просто простой пример, который я построил для проверки своей теории.

Я лично думал, что это будет сложнее;Я доказал, что ошибался.

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...