ayltai / mopub-nativead-adapters Goto Github PK
View Code? Open in Web Editor NEWCustom adapters for MoPub native ads
License: Apache License 2.0
Custom adapters for MoPub native ads
License: Apache License 2.0
i have included your project to my gradle and all was going fine with my implementaion for medaition of MoPub with Facebook : but i got a pop with this error in my log
Caused by: java.lang.ClassNotFoundException: Didn't find class "org.github.ayltai.mopub.adapter.FacebookNativeAd" on path: DexPathList[[zip file "/data/app/com.ezydev.phonecompare-2/base.apk"],nativeLibraryDirectories=[/data/app/com.ezydev.phonecompare-2/lib/arm, /vendor/lib, /system/lib]]
@OverRide
public void onNativeLoad(final com.mopub.nativeads.NativeAd nativeAd) {
Log.i(this.getClass().getSimpleName(), "Native ad loaded");nativeAd.setMoPubNativeEventListener(this); final StaticNativeAd staticNativeAd = (StaticNativeAd)nativeAd.getBaseNativeAd(); if (staticNativeAd instanceof FacebookNativeAd) { Log.i(this.getClass().getSimpleName(), "Native ad loaded FacebookNativeAd"); } }
Hi @ayltai, thank you for building this sample app. I'm looking for feedback on implementing the manual MoPub
object integration with a RecyclerView?
I've followed the MoPubNative
manual setup, and can see via the logs the ad view is received from the getAdView
request. However, I am having trouble with Step 2. Render the Native Ad, and doing so within the RecyclerView
pattern.
With the existing ContentViewHolder
the content data is bound and parsed in the layout cell_content.xml with the data represented by the Content
model. For the MoPub ad view the data is described in the ViewBinder
, therefore it seems this should bind the created view to the native_ad_item.xml layout. When an ad cell is reached there is an error due to an incorrect binding. May you please advise on rendering the created ad view using the ViewHolder
pattern?
Error
ConstraintLayout cannot be cast to com.mopub.nativeads.ViewBinder
Adapter.kt
class ContentAdapter(var context: Context, var contentViewModel: ContentViewModel,
var homeViewModel: HomeViewModel,
var moPubAdapterHelper: AdapterHelper) : PagedListAdapter<Content, RecyclerView.ViewHolder>(DIFF_CALLBACK) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
if (viewType == MOPUB_NATIVE_ROW_TYPE) {
val binding = NativeAdItemBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
return AdsViewHolder(binding)
} else {
val binding = CellContentBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
binding.viewmodel = contentViewModel
return ContentViewHolder(binding)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (getItemViewType(position) == MOPUB_NATIVE_ROW_TYPE) {
val viewBinder = ViewBinder.Builder(app.coinverse.R.layout.native_ad_item)
.titleId(app.coinverse.R.id.native_title)
.textId(app.coinverse.R.id.native_text)
.mainImageId(app.coinverse.R.id.native_main_image)
.iconImageId(app.coinverse.R.id.native_icon_image)
.callToActionId(app.coinverse.R.id.native_cta)
.privacyInformationIconImageId(app.coinverse.R.id.native_privacy_information_icon_image)
.build()
if (homeViewModel.moPubInitialized) {
val moPubNative = MoPubNative(context, AD_UNIT_ID,
object : MoPubNative.MoPubNativeNetworkListener {
override fun onNativeLoad(nativeAd: NativeAd) {
// How to render ad view with RecyclerAdapter?
val adView = moPubAdapterHelper.getAdView(null, null,
nativeAd, ViewBinder.Builder(0).build())
(holder as AdsViewHolder).bind(adView)
nativeAd.setMoPubNativeEventListener(object : NativeAd.MoPubNativeEventListener {
override fun onImpression(view: View) {
Log.d("MoPub", "Native ad recorded an impression.")
}
override fun onClick(view: View) {
Log.d("MoPub", "Native ad recorded a click.")
}
})
}
override fun onNativeFail(errorCode: NativeErrorCode?) {
Log.e(LOG_TAG, "Native ad fail: ${errorCode}")
}
})
moPubNative.registerAdRenderer(MoPubStaticNativeAdRenderer(viewBinder))
moPubNative.makeRequest()
}
} else {
getItem(position).let { content -> if (content != null) (holder as ContentViewHolder).bind(createOnClickListener(content), content) }
}
}
override fun getItemCount() = moPubAdapterHelper.shiftedCount(super.getItemCount())
override fun getItem(position: Int) = super.getItem(moPubAdapterHelper.shiftedPosition(position))
override fun getItemViewType(position: Int) =
if (moPubAdapterHelper.isAdPosition(position)) MOPUB_NATIVE_ROW_TYPE
else super.getItemViewType(moPubAdapterHelper.shiftedPosition(position))
inner class AdsViewHolder(private var binding: ViewDataBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(data: Any) {
binding.setVariable(BR.data, data)
binding.executePendingBindings()
}
}
inner class ContentViewHolder(private var binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(onClickListener: OnClickListener, data: Any) {
binding.setVariable(BR.data, data)
binding.setVariable(BR.clickListener, onClickListener)
binding.root.preview.setTag(ADAPTER_POSITION_KEY, layoutPosition)
binding.executePendingBindings()
}
}
}
cell_content.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="data"
type="app.coinverse.content.models.Content" />
<variable
name="viewmodel"
type="app.coinverse.content.ContentViewModel" />
<variable
name="contentType"
type="app.coinverse.Enums.ContentType" />
<variable
name="clickListener"
type="android.view.View.OnClickListener" />
</data>
<androidx.cardview.widget.CardView
android:id="@+id/contentCard"
style="@style/CellCardStyle">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cell_content_feed"
style="@style/CellConstraintStyle">
<TextView
android:id="@+id/creator"
style="@style/CellCreatorStyle"
android:text='@{data.creator, default="creator name"}'
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/timeAgo"
style="@style/TimeAgoStyle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/creator"
app:timePostedAgo="@{data.timestamp.toDate().time}"
tools:text="time ago posted" />
<ImageView
android:id="@+id/contentTypeLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/youtube_content_type_content_description"
app:contentTypeIcon="@{data.contentType != null ? data.contentType : contentType.NONE}"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@id/creator" />
<ImageView
android:id="@+id/preview"
style="@style/CellPreviewImageStyle"
android:onClick="@{clickListener}"
app:imageUrl="@{data.previewImage}"
app:layout_constraintBottom_toTopOf="@id/title"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/timeAgo" />
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{viewmodel.getLoadingState(data.id)}"
app:layout_constraintBottom_toBottomOf="@id/preview"
app:layout_constraintLeft_toLeftOf="@id/preview"
app:layout_constraintRight_toRightOf="@id/preview"
app:layout_constraintTop_toTopOf="@id/preview" />
<TextView
android:id="@+id/title"
style="@style/CellTitleStyle"
android:text='@{data.title, default="content title"}'
app:layout_constraintBottom_toTopOf="@id/share"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/preview" />
<ImageView
android:id="@+id/openSource"
style="@style/IconButtonStyle"
android:background="?attr/selectableItemBackgroundBorderless"
android:onClick="@{clickListener}"
android:src="@drawable/ic_open_in_browser_black_24dp"
android:tooltipText="@string/open_source_tip"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@id/share"
app:layout_constraintTop_toBottomOf="@id/title" />
<ImageView
android:id="@+id/share"
style="@style/IconButtonStyle"
android:background="?attr/selectableItemBackgroundBorderless"
android:onClick="@{clickListener}"
android:src="@drawable/ic_rocket_black"
android:tooltipText="@string/share_content_tip"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/title" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</layout>
native_ad_item.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="data"
type="com.mopub.nativeads.ViewBinder" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/native_outer_view"
style="@style/AdContentCardStyle"
android:textDirection="locale">
<TextView
android:id="@+id/native_title"
style="@style/CellCreatorStyle"
app:layout_constraintBottom_toBottomOf="@+id/guideline"
app:layout_constraintLeft_toLeftOf="parent" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toTopOf="@id/native_main_image"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/sponsored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sponsored"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/guideline" />
<ImageView
android:id="@+id/native_icon_image"
android:layout_width="@dimen/native_icon_image_dimen"
android:layout_height="@dimen/native_icon_image_dimen"
android:background="@null"
android:contentDescription="@string/native_icon_mage"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/native_main_image"
style="@style/CellPreviewImageStyle"
android:background="@null"
android:contentDescription="@string/native_main_image"
android:scaleType="centerCrop"
app:layout_constraintBottom_toTopOf="@id/native_text"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/sponsored" />
<TextView
android:id="@+id/native_text"
style="@style/CellTitleStyle"
app:layout_constraintBottom_toTopOf="@id/native_cta"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/native_main_image" />
<TextView
android:id="@+id/native_cta"
style="@style/NativeCtaStyle"
android:background="?attr/selectableItemBackground"
android:clickable="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/native_text"
tools:text="@string/learn_more" />
<ImageView
android:id="@+id/native_privacy_information_icon_image"
android:layout_width="@dimen/native_privacy_info_icon_image_dimen"
android:layout_height="@dimen/native_privacy_info_icon_image_dimen"
android:contentDescription="@string/native_privacy_information_icon_image"
app:layout_constraintBottom_toBottomOf="@id/native_cta"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@id/native_cta" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.