Реклама AdMob в бесконечном RecyclerView с библиотекой подкачки - PullRequest
3 голосов
/ 05 июня 2019

Я использую библиотеку подкачки для извлечения данных с сервера, я думал о том, чтобы показывать рекламу после каждых 10 элементов.Поэтому, когда пользователь прокручивает страницу вниз, новые элементы выбираются и добавляются в PagedList.Я хочу, чтобы новое объявление загружалось и добавлялось в RecyclerView так же, как Instagram показывает рекламу в каналах.Так что, если пользователь прокрутит до 200 элементов, 20 объявлений будут показываться постепенно !!.Я прочитал несколько учебных пособий, но я не нашел простого способа сделать это.

Вот мой адаптер.

class RequestsPagedAdapter(
        private val retryCallback: () -> Unit, private val from: From)
    : PagedListAdapter<RequestsQuery.Request, RecyclerView.ViewHolder>(POST_COMPARATOR) {
    private var networkState: NetworkState? = null

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (getItemViewType(position)) {
            R.layout.z_request_item -> (holder as RequestViewHolder).bind(getItem(position)!!, from)
            R.layout.network_state_item -> (holder as NetworkStateItemViewHolder).bindTo(networkState)
            R.layout.ad_admob_banner -> (holder as AdMobViewHolder)
        }
    }

    override fun onBindViewHolder(
            holder: RecyclerView.ViewHolder,
            position: Int,
            payloads: MutableList<Any>) {
        if (payloads.isNotEmpty()) {
            val item = getItem(position)
            (holder as RequestViewHolder).updateProduct(item!!)
        } else {
            onBindViewHolder(holder, position)
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            R.layout.z_request_item -> RequestViewHolder.create(parent)
            R.layout.network_state_item -> NetworkStateItemViewHolder.create(parent, retryCallback)
            R.layout.ad_admob_banner -> AdMobViewHolder.create(parent)
            else -> throw IllegalArgumentException("unknown view type $viewType")
        }
    }

    private fun hasExtraRow() = networkState != null && networkState != NetworkState.LOADED

    override fun getItemViewType(position: Int): Int {
        return when {
            hasExtraRow() && position == itemCount - 1 -> R.layout.network_state_item
            position % ITEMS_PER_AD == 0 + 2 -> R.layout.ad_admob_banner
            else -> R.layout.z_request_item
        }
    }

    override fun getItemCount(): Int {
        return super.getItemCount() + if (hasExtraRow()) 1 else 0
    }

    fun setNetworkState(newNetworkState: NetworkState?) {
        val previousState = this.networkState
        val hadExtraRow = hasExtraRow()
        this.networkState = newNetworkState
        val hasExtraRow = hasExtraRow()
        if (hadExtraRow != hasExtraRow) {
            if (hadExtraRow) {
                notifyItemRemoved(super.getItemCount())
            } else {
                notifyItemInserted(super.getItemCount())
            }
        } else if (hasExtraRow && previousState != newNetworkState) {
            notifyItemChanged(itemCount - 1)
        }
    }

    companion object {
        val POST_COMPARATOR = object : DiffUtil.ItemCallback<RequestsQuery.Request>() {
            override fun areContentsTheSame(oldItem: RequestsQuery.Request, newItem: RequestsQuery.Request): Boolean =
                    oldItem == newItem

            override fun areItemsTheSame(oldItem: RequestsQuery.Request, newItem: RequestsQuery.Request): Boolean =
                    oldItem.id() == newItem.id()
        }
    }
}

Это то, как данные отправляются на PagedListот Fragment.

private fun getRequests() {
    subcategoryRequestsListViewModel.requests.observe(viewLifecycleOwner, Observer {
        adapter.submitList(it)
    })
    subcategoryRequestsListViewModel.networkState.observe(viewLifecycleOwner, Observer {
        adapter.setNetworkState(it)
    })
}

И ViewHolder

class AdMobViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    companion object {
        fun create(parent: ViewGroup): AdMobViewHolder {
            val view = LayoutInflater.from(parent.context)
                    .inflate(R.layout.ad_admob_banner, parent, false)
            return AdMobViewHolder(view)
        }
    }
}

Ответы [ 3 ]

1 голос
/ 06 июля 2019

первый шаг должен быть объявлен как поле в адаптере, например blew

private val ADS_ITEM = 0
private val NORMAL_ITEM = 1

, поэтому на следующем шаге вы должны создать экземпляр типа viewHolder

inner class MyViewHolder(itemView: View) : ViewHolder(itemView) {
    var title: TextView = itemView.item_text

}

inner class AdsMyViewHolder(itemView: View) : ViewHolder(itemView) {
    var title: TextView = itemView.item_text
}

и создать новыйподходящий экземпляр viewHolder

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val inflater = LayoutInflater.from(parent.context)
    return if (viewType == NORMAL_ITEM) {
        val v = inflater.inflate(R.layout.item, parent, false)
        vh = MyViewHolder(v)
        vh as MyViewHolder
    } else {
        val v = inflater.inflate(R.layout.item_ads, parent, false)
        vh = AdsMyViewHolder(v)
        vh as AdsMyViewHolder
    }
}

не забудьте переопределить getItemViewType

override fun getItemViewType(position: Int): Int {
    return when (getItems()[position]) {
        is AdsSampleModel -> ADS_ITEM
        else -> NORMAL_ITEM
    }
}

последний шаг: привязать элемент с подходящими данными

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    when (holder) {
        is MyViewHolder -> {
            vh = holder
            val model = getItems()[position] as SampleModel
            (vh as MyViewHolder).title.text = model.getId().toString()
        }
        else -> {
            vh = holder
            val model = getItems()[position] as AdsSampleModel
            (vh as AdsMyViewHolder).title.text = model.getText()
        }
    }
}

добавить новый элемент после подкачки

fun view () {
    endless = object : EndlessRecyclerViewScrollListener(layoutManager) {
        fun onLoadMore(page: Int, totalItemsCount: Int, view: RecyclerView) {
            getNext()
        }
    }
    recyclerView.addOnScrollListener(endless)
}


fun getNext() {
    if (hasNextPage) {
        page++
        val callBack = object : YourCallback {
            override fun onSuccess(response: ResponseValue?) {
                if (response!!.getList().size() == 0)
                    hasNextPage = false
                else
                    addData(response!!.getList())
            }
            override fun onError() {
                // error handling
            }
        }
    }
}


private fun addData(models: List<YourModel>?) {
    for (i in models?.indices) {
        if (i % 10 == 0) {
            list.add(ADS_TYPE)
        }
    }

    // notify adapter must be doing by main thread
    runOnUiThread { adapter.notifyDataSetChanged() }
}
1 голос
/ 09 июля 2019

Здесь не может быть простого примера, чем пример Google здесь Единственное отличие состоит в том, что он берет данные из XML-файла, сохраненного в raw, и вы берете свои данные из другого места.Я надеюсь, что вы можете легко изменить этот пример в соответствии с вашими потребностями.

0 голосов
/ 04 июля 2019

Вы можете использовать встроенную расширенную рекламу AdMob в ленте Android.

Native - это формат объявлений на основе компонентов, который дает издателям свободу настраивать способ представления рекламных активов, таких как заголовки и призывы к действию, в своих приложениях. Выбирая шрифты, цвета и другие детали для себя, издатели могут создавать естественные, ненавязчивые рекламные презентации, которые могут добавить богатый пользовательский опыт. Пожалуйста, перейдите по указанной ниже ссылке: -

https://codelabs.developers.google.com/codelabs/admob-native-advanced-feed-android/#0

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