Native
Native ad is a flexible type of advertising. You can adapt the display to your UI by preparing a template.
You can use our demo app as a reference project.
Cache
To cache native ads, use:
- Kotlin
- Java
Appodeal.cache(this, Appodeal.NATIVE)
Appodeal.cache(this, Appodeal.NATIVE);
To cache multiple native ads, use:
- Kotlin
- Java
Appodeal.cache(this, Appodeal.NATIVE, 3)
Appodeal.cache(this, Appodeal.NATIVE, 3);
The number of cached ads is not guaranteed and could be less than requested.
Check If Ad Is Loaded
- Kotlin
- Java
Appodeal.isLoaded(Appodeal.NATIVE)
Appodeal.isLoaded(Appodeal.NATIVE);
Get Loaded Native Ads
To get loaded native ads, use the following method:
- Kotlin
- Java
val nativeAds: List<NativeAd> = Appodeal.getNativeAds(amount)
List<NativeAd> nativeAds = Appodeal.getNativeAds(int amount);
Once you get the ads, they are removed from our SDK cache.
Callbacks
- Kotlin
- Java
Appodeal.setNativeCallbacks(object : NativeCallbacks {
override fun onNativeLoaded() {
// Called when native ads are loaded
}
override fun onNativeFailedToLoad() {
// Called when native ads are failed to load
}
override fun onNativeShown(NativeAd nativeAd) {
// Called when native ad is shown
}
override fun onNativeShowFailed(NativeAd nativeAd) {
// Called when native ad show failed
}
override fun onNativeClicked(NativeAd nativeAd) {
// Called when native ads is clicked
}
override fun onNativeExpired() {
// Called when native ads is expired
}
})
Appodeal.setNativeCallbacks(new NativeCallbacks() {
@Override
public void onNativeLoaded() {
// Called when native ads are loaded
}
@Override
public void onNativeFailedToLoad() {
// Called when native ads are failed to load
}
@Override
public void onNativeShown(NativeAd nativeAd) {
// Called when native ad is shown
}
@Override
public void onNativeShowFailed(NativeAd nativeAd) {
// Called when native ad show failed
}
@Override
public void onNativeClicked(NativeAd nativeAd) {
// Called when native ads is clicked
}
@Override
public void onNativeExpired() {
// Called when native ads is expired
}
});
All callbacks are called on the main thread.
Cache Manually
To disable automatic caching for native ads, use the code below before the SDK initialization:
- Kotlin
- Java
Appodeal.setAutoCache(Appodeal.NATIVE, false)
Appodeal.setAutoCache(Appodeal.NATIVE, false);
Read more on manual caching in our FAQ.
Get Available Native Ads Count
- Kotlin
- Java
Appodeal.getAvailableNativeAdsCount()
Appodeal.getAvailableNativeAdsCount();
NativeAd Object
After getting loaded native ads using Appodeal.getNativeAds()
, a list of NativeAd objects is returned.
- Kotlin
- Java
Name of methods | Type | Mandatory | Description |
---|---|---|---|
nativeAd.title | String | Mandatory | Title of the native ad. Maximum 25 symbols of the title should always be displayed. You can add ellipsis at the end if the title is longer. |
nativeAd.callToAction | String | Mandatory | Call-to-action text. Should be displayed without truncation on a visible button. |
nativeAd.description | String | Optional | Text description of the native ad. If you choose to display the description, you should display maximum 100 characters. You can add ellipsis at the end. |
nativeAd.rating | Float | Optional | Rating of the app in [0-5] range |
nativeAd.ageRestrictions | String | Optional | App age restriction. May return null . |
nativeAd.adProvider | String | Optional | Gets provider name of native ad. |
nativeAd.getProviderView(context: Context) | View | Mandatory | If it doesn’t return null , it’s mandatory to display the provider icon in any corner of the native ad. Used by some networks to display AdChoices or the privacy icon. |
nativeAd.containsVideo() | Boolean | Optional | Returns true, if NativeAd object contains the video. |
nativeAd.canShow(placementName: String) | Boolean | Optional | Check if native ad can be shown with the placement. |
nativeAd.isPrecache | Boolean | Optional | Check if a native ad is precache. |
nativeAd.predictedEcpm | Double | Optional | Returns the predicted ecpm for creative. |
nativeAd.destroy() | Unit | Mandatory | Destroys the native ad, unregisters from tracking. |
Name of methods | Type | Mandatory | Description |
---|---|---|---|
nativeAd.getTitle() | String | Mandatory | Title of the native ad. Maximum 25 symbols of the title should always be displayed. You can add ellipsis at the end if the title is longer. |
nativeAd.getCallToAction() | String | Mandatory | Call-to-action text. Should be displayed without truncation on a visible button. |
nativeAd.getDescription() | String | Optional | Text description of the native ad. If you choose to display the description, you should display maximum 100 characters. You can add ellipsis at the end. |
nativeAd.getRating() | Float | Optional | Rating of the app in [0-5] range |
nativeAd.getAgeRestrictions() | String | Optional | App age restriction. May return null . |
nativeAd.getAdProvider() | String | Optional | Gets provider name of native ad. |
nativeAd.getProviderView(Context context) | View | Mandatory | If it doesn’t return null , it’s mandatory to display the provider icon in any corner of the native ad. Used by some networks to display AdChoices or the privacy icon. |
nativeAd.containsVideo() | Boolean | Optional | Returns true, if NativeAd object contains the video. |
nativeAd.canShow(String placementName) | Boolean | Optional | Check if native ad can be shown with the placement. |
nativeAd.isPrecache() | Boolean | Optional | Check if a native ad is precache. |
nativeAd.getPredictedEcpm() | Double | Optional | Returns the predicted ecpm for creative. |
nativeAd.destroy() | Void | Mandatory | Destroys the native ad, unregisters from tracking. |
Configuration
Native Ads Assets Caching
Set required native media assets for what necessary for the show. Default value is ALL
.
- Kotlin
- Java
//assets caching for NativeIconView and NativeMediaView
Appodeal.setRequiredNativeMediaAssetType(Native.MediaAssetType.ALL)
//assets caching only for NativeIconView
Appodeal.setRequiredNativeMediaAssetType(Native.MediaAssetType.ICON)
//assets caching only for NativeMediaView
Appodeal.setRequiredNativeMediaAssetType(Native.MediaAssetType.IMAGE)
//assets caching for NativeIconView and NativeMediaView
Appodeal.setRequiredNativeMediaAssetType(Native.MediaAssetType.ALL);
//assets caching only for NativeIconView
Appodeal.setRequiredNativeMediaAssetType(Native.MediaAssetType.ICON);
//assets caching only for NativeMediaView
Appodeal.setRequiredNativeMediaAssetType(Native.MediaAssetType.IMAGE);
Native Video
To show video native ads, add NativeMediaView
to native ad layout.
- Kotlin
- Java
val adView: NativeAdView = findViewById(R.id.native_layout)
val nativeMediaView: NativeMediaView = adView.findViewById(R.id.appodeal_media_view_content)
if (nativeAd.containsVideo()) {
adView.nativeMediaView = nativeMediaView;
} else {
nativeMediaView.visibility = View.GONE;
}
NativeAdView adView = findViewById(R.id.native_layout)
NativeMediaView nativeMediaView = adView.findViewById(R.id.appodeal_media_view_content);
if (nativeAd.containsVideo()) {
nativeAdView.setNativeMediaView(nativeMediaView);
} else {
nativeMediaView.setVisibility(View.GONE);
}
Native Video Settings
To control whether you want to show video native ads, use the following methods:
- Kotlin
- Java
// both static image and video native ads will be loaded
Appodeal.setNativeAdType(Native.NativeAdType.Auto)
// only static image native ads will be loaded
Appodeal.setNativeAdType(Native.NativeAdType.NoVideo)
// only video native ads will be loaded.
Appodeal.setNativeAdType(Native.NativeAdType.Video)
// both static image and video native ads will be loaded
Appodeal.setNativeAdType(Native.NativeAdType.Auto);
// only static image native ads will be loaded
Appodeal.setNativeAdType(Native.NativeAdType.NoVideo);
// only video native ads will be loaded.
Appodeal.setNativeAdType(Native.NativeAdType.Video);
Templates
Appodeal SDK provides 3 types of templates for native ads:
NativeAdViewNewsFeed
;NativeAdViewAppWall
;NativeAdViewContentStream
.
If you want to use one of these templates, you can add the selected template in the layout:
<com.appodeal.ads.native_ad.views.NativeAdViewNewsFeed
android:id="@+id/native_ad_view_news_feed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp">
</com.appodeal.ads.native_ad.views.NativeAdViewNewsFeed>
<com.appodeal.ads.native_ad.views.NativeAdViewAppWall
android:id="@+id/native_ad_view_app_wall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp">
</com.appodeal.ads.native_ad.views.NativeAdViewAppWall>
<com.appodeal.ads.native_ad.views.NativeAdViewContentStream
android:id="@+id/native_ad_view_content_stream"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp">
</com.appodeal.ads.native_ad.views.NativeAdViewContentStream>
And when you need to show the ad:
- Kotlin
- Java
val nav_nf: NativeAdViewNewsFeed = mActivity.findViewById(R.id.native_ad_view_news_feed)
nav_nf.setNativeAd(mNativeAd)
val nav_aw: NativeAdViewAppWall = mActivity.findViewById(R.id.native_ad_view_app_wall)
nav_aw.setNativeAd(mNativeAd)
val nav_cs: NativeAdViewContentStream = mActivity.findViewById(R.id.native_ad_view_content_stream)
nav_cs.setNativeAd(mNativeAd)
NativeAdViewNewsFeed nav_nf = mActivity.findViewById(R.id.native_ad_view_news_feed);
nav_nf.setNativeAd(mNativeAd);
NativeAdViewAppWall nav_aw = mActivity.findViewById(R.id.native_ad_view_app_wall);
nav_aw.setNativeAd(mNativeAd);
NativeAdViewContentStream nav_cs = mActivity.findViewById(R.id.native_ad_view_content_stream);
nav_cs.setNativeAd(mNativeAd);
You can also create a view programmatically and add it to the screen:
- Kotlin
- Java
val holder: RelativeLayout = mActivity.findViewById(R.id.native_template_holder)
val nativeAdView = NativeAdViewAppWall(mActivity, mNativeAd)
holder.addView(nativeAdView)
RelativeLayout holder = mActivity.findViewById(R.id.native_template_holder);
NativeAdViewAppWall nativeAdView = new NativeAdViewAppWall(mActivity, mNativeAd);
holder.addView(nativeAdView);
TemplateElements
- Kotlin
- Java
val title: TextView = getTitleView()
val description: TextView = getDescriptionView()
val rating: View = getRatingView()
val ratingBar: RatingBar = getRatingBar()
val providerView: View = getProviderView()
val callToAction: TextView = getCallToActionView()
val iconView: NativeIconView = getNativeIconView()
val mediaView: NativeMediaView = getNativeMediaView()
TextView title = getTitleView();
TextView description = getDescriptionView();
View rating = getRatingView();
RatingBar ratingBar = getRatingBar();
View providerView = getProviderView();
TextView callToAction = getCallToActionView();
NativeIconView iconView = getNativeIconView();
NativeMediaView mediaView = getNativeMediaView();
By default, native ads are labeled «Ad». You can replace it with «Sponsored» for the native templates:
- Kotlin
- Java
nav.showSponsored(true);
nav.showSponsored(true)
To change the color of the call-to-action button in the native templates, use:
- Kotlin
- Java
nav.setCallToActionColor(color: Integer)
nav.setCallToActionColor(color: String)
nav.setCallToActionColor(int color);
nav.setCallToActionColor(String color);
СustomLayout
- Kotlin
- Java
val nativeAdView: NativeAdView = findViewById(R.id.native_layout)
val tvTitle: TextView = nativeAdView.findViewById(R.id.tv_title)
tvTitle.text = nativeAd.title
nativeAdView.titleView = tvTitle
val tvDescription: TextView = nativeAdView.findViewById(R.id.tv_description)
tvDescription.text = nativeAd.description
nativeAdView.descriptionView = tvDescription
val ratingBar: RatingBar = nativeAdView.findViewById(R.id.rb_rating)
if (nativeAd.rating == 0.0f) {
ratingBar.visibility = View.INVISIBLE
} else {
ratingBar.visibility = View.VISIBLE
ratingBar.rating = nativeAd.rating
ratingBar.stepSize = 0.1f
}
nativeAdView.ratingView = ratingBar
val ctaButton: Button = nativeAdView.findViewById(R.id.b_cta)
ctaButton.text = nativeAd.callToAction
nativeAdView.callToActionView = ctaButton
val providerView: View? = nativeAd.getProviderView(context)
if (providerView != null) {
if (providerView.parent != null && providerView.parent is ViewGroup) {
(providerView.parent as ViewGroup).removeView(providerView)
}
val providerViewContainer: FrameLayout =
nativeAdView.findViewById(R.id.provider_view)
val layoutParams: ViewGroup.LayoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
providerViewContainer.addView(providerView, layoutParams)
}
nativeAdView.providerView = providerView
val tvAgeRestrictions: TextView = nativeAdView.findViewById(R.id.tv_age_restriction)
if (nativeAd.ageRestrictions != null) {
tvAgeRestrictions.text = nativeAd.ageRestrictions
tvAgeRestrictions.visibility = View.VISIBLE
} else {
tvAgeRestrictions.visibility = View.GONE
}
val nativeIconView: NativeIconView = nativeAdView.findViewById(R.id.icon)
nativeAdView.setNativeIconView(nativeIconView)
val nativeMediaView: NativeMediaView = nativeAdView.findViewById(R.id.appodeal_media_view_content)
nativeAdView.nativeMediaView = nativeMediaView
nativeAdView.registerView(nativeAd)
NativeAdView nativeAdView = (NativeAdView) findViewById(R.id.native_layout)
TextView tvTitle = (TextView) nativeAdView.findViewById(R.id.tv_title);
tvTitle.setText(nativeAd.getTitle());
nativeAdView.setTitleView(tvTitle);
TextView tvDescription = (TextView) nativeAdView.findViewById(R.id.tv_description);
tvDescription.setText(nativeAd.getDescription());
nativeAdView.setDescriptionView(tvDescription);
RatingBar ratingBar = nativeAdView.findViewById(R.id.rb_rating);
if (nativeAd.getRating() == 0) {
ratingBar.setVisibility(View.INVISIBLE);
} else {
ratingBar.setVisibility(View.VISIBLE);
ratingBar.setRating(nativeAd.getRating());
ratingBar.setStepSize(0.1f);
}
nativeAdView.setRatingView(ratingBar);
Button ctaButton = nativeAdView.findViewById(R.id.b_cta);
ctaButton.setText(nativeAd.getCallToAction());
nativeAdView.setCallToActionView(ctaButton);
View providerView = nativeAd.getProviderView(context);
if (providerView != null) {
if (providerView.getParent() != null && providerView.getParent() instanceof ViewGroup) {
((ViewGroup) providerView.getParent()).removeView(providerView);
}
FrameLayout providerViewContainer = nativeAdView.findViewById(R.id.provider_view);
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
providerViewContainer.addView(providerView, layoutParams);
}
nativeAdView.setProviderView(providerView);
TextView tvAgeRestrictions = nativeAdView.findViewById(R.id.tv_age_restriction);
if (nativeAd.getAgeRestrictions() != null) {
tvAgeRestrictions.setText(nativeAd.getAgeRestrictions());
tvAgeRestrictions.setVisibility(View.VISIBLE);
} else {
tvAgeRestrictions.setVisibility(View.GONE);
}
NativeIconView nativeIconView = nativeAdView.findViewById(R.id.icon);
nativeAdView.setNativeIconView(nativeIconView);
NativeMediaView nativeMediaView = nativeAdView.findViewById(R.id.appodeal_media_view_content);
nativeAdView.setNativeMediaView(nativeMediaView);
nativeAdView.registerView(nativeAd);
To showNativeAdin custom layout you should use NativeAdView
, populate and register the asset views.
Bind assets view to NativeAdView
:
- Kotlin
- Java
nativeAdView.titleView = view: View
nativeAdView.callToActionView = view: View
nativeAdView.ratingView = view: View
nativeAdView.descriptionView = view: View
nativeAdView.providerView = view: View
nativeAdView.setNativeIconView(nativeIconView: NativeIconView)
nativeAdView.nativeMediaView = nativeMediaView: NativeMediaView
nativeAdView.setTitleView(View view);
nativeAdView.setCallToActionView(View view);
nativeAdView.setRatingView(View view);
nativeAdView.setDescriptionView(View view);
nativeAdView.setProviderView(View view);
nativeAdView.setNativeIconView(NativeIconView nativeIconView);
nativeAdView.setNativeMediaView(NativeMediaView nativeMediaView);
And registerNativeAdobject in NativeAdView:
- Kotlin
- Java
nativeAdView.registerView(nativeAd: NativeAd)
// or nativeAdView.registerView(nativeAd: NativeAd, placementName: String) if you use placements
nativeAdView.registerView(NativeAd nativeAd);
// or nativeAdView.registerView(NativeAd nativeAd, String placementName); if you use placements
If another NativeAd was registered to this instance of view, it will be automatically unregistered.
To unregister NativeAd from NativeAdView
, call:
- Kotlin
- Java
nativeAdView.unregisterViewForInteraction();
nativeAdView.unregisterViewForInteraction()
If NativeAdView
is reused to display the same ad or to display other ads, it's better to call
the unregisterViewForInteraction()
method before you can register the same view with another instance
of NativeAd
.
To destroy NativeAd that was registered to NativeAdView
, you should call:
- Kotlin
- Java
nativeAdView.destroy()
nativeAdView.destroy();
You can't use this instance on NativeAdView
after call destroy()
. You should hide this view or
register another NativeAd.
Integration Example
- Kotlin
- Java
fun loadNativeAds() {
Appodeal.setRequiredNativeMediaAssetType(Native.MediaAssetType.ICON)
Appodeal.initialize(this, YOUR_APP_KEY, Appodeal.NATIVE, consentValue)
Appodeal.setNativeCallbacks(new NativeCallbacks() {
override fun onNativeLoaded() {
Toast.makeText(MainActivity.this, "onNativeLoaded", Toast.LENGTH_SHORT).show()
}
override fun onNativeFailedToLoad() {
Toast.makeText(MainActivity.this, "onNativeFailedToLoad", Toast.LENGTH_SHORT).show()
}
override fun onNativeShown(NativeAd nativeAd) {
Toast.makeText(MainActivity.this, "onNativeShown", Toast.LENGTH_SHORT).show()
}
override fun onNativeClicked(NativeAd nativeAd) {
Toast.makeText(MainActivity.this, "onNativeClicked", Toast.LENGTH_SHORT).show()
}
override fun onNativeExpired() {
Toast.makeText(MainActivity.this, "onNativeExpired", Toast.LENGTH_SHORT).show()
}
})
}
public void loadNativeAds() {
Appodeal.setRequiredNativeMediaAssetType(Native.MediaAssetType.ICON);
Appodeal.initialize(this, YOUR_APP_KEY, Appodeal.NATIVE, consentValue);
Appodeal.setNativeCallbacks(new NativeCallbacks() {
@Override
public void onNativeLoaded() {
Toast.makeText(MainActivity.this, "onNativeLoaded", Toast.LENGTH_SHORT).show();
}
@Override
public void onNativeFailedToLoad() {
Toast.makeText(MainActivity.this, "onNativeFailedToLoad", Toast.LENGTH_SHORT).show();
}
@Override
public void onNativeShown(NativeAd nativeAd) {
Toast.makeText(MainActivity.this, "onNativeShown", Toast.LENGTH_SHORT).show();
}
@Override
public void onNativeClicked(NativeAd nativeAd) {
Toast.makeText(MainActivity.this, "onNativeClicked", Toast.LENGTH_SHORT).show();
}
@Override
public void onNativeExpired() {
Toast.makeText(MainActivity.this, "onNativeExpired", Toast.LENGTH_SHORT).show();
}
});
};
To show loaded native ad:
- Kotlin
- Java
fun showNativeAd() {
val loadedNativeAds = Appodeal.getNativeAds(1)
if (loadedNativeAds.isEmpty()) {
//Native Ads not loaded yet
return
}
val nativeAd = loadedNativeAds[0]
val nativeAdView: NativeAdView = findViewById(R.id.native_layout)
val tvTitle: TextView = nativeAdView.findViewById(R.id.tv_title)
tvTitle.text = nativeAd.title
nativeAdView.titleView = tvTitle
val tvDescription: TextView = nativeAdView.findViewById(R.id.tv_description)
tvDescription.text = nativeAd.description
nativeAdView.descriptionView = tvDescription
val ratingBar: RatingBar = nativeAdView.findViewById(R.id.rb_rating)
if (nativeAd.rating == 0f) {
ratingBar.visibility = View.INVISIBLE
} else {
ratingBar.visibility = View.VISIBLE
ratingBar.rating = nativeAd.rating
ratingBar.stepSize = 0.1f
}
nativeAdView.ratingView = ratingBar
val ctaButton: Button = nativeAdView.findViewById(R.id.b_cta)
ctaButton.text = nativeAd.callToAction
nativeAdView.callToActionView = ctaButton
val providerView = nativeAd.getProviderView(context)
if (providerView != null) {
if (providerView.parent != null && providerView.parent is ViewGroup) {
(providerView.parent as ViewGroup).removeView(providerView)
}
val providerViewContainer: FrameLayout = nativeAdView.findViewById(R.id.provider_view)
val layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
providerViewContainer.addView(providerView, layoutParams)
}
nativeAdView.providerView = providerView
val tvAgeRestrictions: TextView = nativeAdView.findViewById(R.id.tv_age_restriction)
if (nativeAd.ageRestrictions != null) {
tvAgeRestrictions.text = nativeAd.ageRestrictions
tvAgeRestrictions.visibility = View.VISIBLE
} else {
tvAgeRestrictions.visibility = View.GONE
}
val nativeIconView: NativeIconView = nativeAdView.findViewById(R.id.icon)
nativeAdView.setNativeIconView(nativeIconView)
val nativeMediaView: NativeMediaView =
nativeAdView.findViewById(R.id.appodeal_media_view_content)
nativeAdView.nativeMediaView = nativeMediaView
nativeAdView.registerView(nativeAd)
nativeAdView.visibility = View.VISIBLE
}
public void showNativeAd(){
List<NativeAd> loadedNativeAds = Appodeal.getNativeAds(1);
if (loadedNativeAds.isEmpty()){
//Native Ads not loaded yet
return;
}
NativeAd nativeAd = loadedNativeAds.get(0);
NativeAdView nativeAdView = (NativeAdView) findViewById(R.id.native_layout);
TextView tvTitle = (TextView) nativeAdView.findViewById(R.id.tv_title);
tvTitle.setText(nativeAd.getTitle());
nativeAdView.setTitleView(tvTitle);
TextView tvDescription = (TextView) nativeAdView.findViewById(R.id.tv_description);
tvDescription.setText(nativeAd.getDescription());
nativeAdView.setDescriptionView(tvDescription);
RatingBar ratingBar = (RatingBar) nativeAdView.findViewById(R.id.rb_rating);
if (nativeAd.getRating() == 0) {
ratingBar.setVisibility(View.INVISIBLE);
} else {
ratingBar.setVisibility(View.VISIBLE);
ratingBar.setRating(nativeAd.getRating());
ratingBar.setStepSize(0.1f);
}
nativeAdView.setRatingView(ratingBar);
Button ctaButton = (Button) nativeAdView.findViewById(R.id.b_cta);
ctaButton.setText(nativeAd.getCallToAction());
nativeAdView.setCallToActionView(ctaButton);
View providerView = nativeAd.getProviderView(context);
if (providerView != null) {
if (providerView.getParent() != null && providerView.getParent() instanceof ViewGroup) {
((ViewGroup) providerView.getParent()).removeView(providerView);
}
FrameLayout providerViewContainer = (FrameLayout) nativeAdView.findViewById(R.id.provider_view);
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
providerViewContainer.addView(providerView, layoutParams);
}
nativeAdView.setProviderView(providerView);
TextView tvAgeRestrictions = (TextView) nativeAdView.findViewById(R.id.tv_age_restriction);
if (nativeAd.getAgeRestrictions() != null) {
tvAgeRestrictions.setText(nativeAd.getAgeRestrictions());
tvAgeRestrictions.setVisibility(View.VISIBLE);
} else {
tvAgeRestrictions.setVisibility(View.GONE);
}
NativeIconView nativeIconView = nativeAdView.findViewById(R.id.icon);
nativeAdView.setNativeIconView(nativeIconView);
NativeMediaView nativeMediaView = (NativeMediaView) nativeAdView.findViewById(R.id.appodeal_media_view_content);
nativeAdView.setNativeMediaView(nativeMediaView);
nativeAdView.registerView(nativeAd);
nativeAdView.setVisibility(View.VISIBLE);
}
Native Ad Integration To The Feed
You can use this example to integrate Native Ad to the existing feed in your application:
- Kotlin
- Java
import android.util.SparseArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.FrameLayout
import android.widget.RatingBar
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.appodeal.ads.*
/**
* Wrapper adapter to show Native Ad in recycler view with fixed step
*
* @param userAdapter user adapter
* @param nativeStep step show [com.appodeal.ads.NativeAd]
*/
class AppodealWrapperAdapter(
userAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>,
nativeStep: Int
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), NativeCallbacks {
private val _userAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>?
private val userAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>
get() = requireNotNull(_userAdapter)
private var nativeStep = DEFAULT_NATIVE_STEP
private val nativeAdList = SparseArray<NativeAd?>()
init {
this._userAdapter = userAdapter
this.nativeStep = nativeStep + 1
userAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onChanged() {
super.onChanged()
notifyDataSetChanged()
fillListWithAd()
}
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
super.onItemRangeInserted(positionStart, itemCount)
notifyDataSetChanged()
fillListWithAd()
}
})
Appodeal.setNativeCallbacks(this)
fillListWithAd()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == VIEW_HOLDER_NATIVE_AD_TYPE) {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.include_native_ads, parent, false)
NativeCustomAdViewHolder(view)
} else {
userAdapter.onCreateViewHolder(parent, viewType)
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is NativeCustomAdViewHolder) {
holder.fillNative(nativeAdList[position])
} else {
userAdapter.onBindViewHolder(holder, getPositionInUserAdapter(position))
}
}
override fun getItemCount(): Int {
var resultCount = 0
resultCount += nativeAdsCount
resultCount += userAdapterItemCount
return resultCount
}
override fun getItemViewType(position: Int): Int {
return if (isNativeAdPosition(position)) {
VIEW_HOLDER_NATIVE_AD_TYPE
} else {
userAdapter.getItemViewType(getPositionInUserAdapter(position))
}
}
override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
super.onViewRecycled(holder)
if (holder is NativeCustomAdViewHolder) {
holder.unregisterViewForInteraction()
}
}
/**
* Destroy all used native ads
*/
fun destroyNativeAds() {
for (i in 0 until nativeAdList.size()) {
val nativeAd = nativeAdList.valueAt(i)
nativeAd!!.destroy()
}
nativeAdList.clear()
}
override fun onNativeLoaded() {
fillListWithAd()
}
override fun onNativeFailedToLoad() {}
override fun onNativeShown(nativeAd: NativeAd?) {}
override fun onNativeShowFailed(nativeAd: NativeAd?) {}
override fun onNativeClicked(nativeAd: NativeAd?) {}
override fun onNativeExpired() {}
/**
* @return count of loaded ads [com.appodeal.ads.NativeAd]
*/
private val nativeAdsCount: Int
get() = nativeAdList.size()
/**
* @return user items count
*/
private val userAdapterItemCount: Int
get() = userAdapter.itemCount
/**
* @param position index in wrapper adapter
* @return `true` if item by position is [com.appodeal.ads.NativeAd]
*/
private fun isNativeAdPosition(position: Int): Boolean {
return nativeAdList[position] != null
}
/**
* Method for searching position in user adapter
*
* @param position index in wrapper adapter
* @return index in user adapter
*/
private fun getPositionInUserAdapter(position: Int): Int {
return position - nativeAdList.size().coerceAtMost(position / nativeStep)
}
/**
* Method for filling list with [com.appodeal.ads.NativeAd]
*/
private fun fillListWithAd() {
var insertPosition = findNextAdPosition()
var nativeAd: NativeAd? = null
while (canUseThisPosition(insertPosition) && nativeAdItem.also { nativeAd = it } != null) {
nativeAdList.put(insertPosition, nativeAd)
notifyItemInserted(insertPosition)
insertPosition = findNextAdPosition()
}
}
/**
* Get native ad item
*
* @return [com.appodeal.ads.NativeAd]
*/
private val nativeAdItem: NativeAd?
get() {
val ads = Appodeal.getNativeAds(1)
return if (ads.isNotEmpty()) ads[0] else null
}
/**
* Method for finding next position suitable for [com.appodeal.ads.NativeAd]
*
* @return position for next native ad view
*/
private fun findNextAdPosition(): Int {
return if (nativeAdList.size() > 0) {
nativeAdList.keyAt(nativeAdList.size() - 1) + nativeStep
} else nativeStep - 1
}
/**
* @param position index in wrapper adapter
* @return `true` if you can add [com.appodeal.ads.NativeAd] to this position
*/
private fun canUseThisPosition(position: Int): Boolean {
return nativeAdList[position] == null && itemCount > position
}
/**
* View holder for create custom [com.appodeal.ads.native_ad.views.NativeAdView]
*/
internal class NativeCustomAdViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val nativeAdView: NativeAdView = itemView.findViewById(R.id.native_item)
private val tvTitle: TextView = itemView.findViewById(R.id.tv_title)
private val tvDescription: TextView = itemView.findViewById(R.id.tv_description)
private val ratingBar: RatingBar = itemView.findViewById(R.id.rb_rating)
private val ctaButton: Button = itemView.findViewById(R.id.b_cta)
private val nativeIconView: NativeIconView = itemView.findViewById(R.id.icon)
private val tvAgeRestrictions: TextView = itemView.findViewById(R.id.tv_age_restriction)
private val nativeMediaView: NativeMediaView = itemView.findViewById(R.id.appodeal_media_view_content)
private val providerViewContainer: FrameLayout = itemView.findViewById(R.id.provider_view)
fun fillNative(nativeAd: NativeAd?) {
tvTitle.text = nativeAd!!.title
tvDescription.text = nativeAd.description
if (nativeAd.rating == 0f) {
ratingBar.visibility = View.INVISIBLE
} else {
ratingBar.visibility = View.VISIBLE
ratingBar.rating = nativeAd.rating
ratingBar.stepSize = 0.1f
}
ctaButton.text = nativeAd.callToAction
val providerView = nativeAd.getProviderView(nativeAdView.context)
if (providerView != null) {
if (providerView.parent != null && providerView.parent is ViewGroup) {
(providerView.parent as ViewGroup).removeView(providerView)
}
providerViewContainer.removeAllViews()
val layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
providerViewContainer.addView(providerView, layoutParams)
}
if (nativeAd.ageRestrictions != null) {
tvAgeRestrictions.text = nativeAd.ageRestrictions
tvAgeRestrictions.visibility = View.VISIBLE
} else {
tvAgeRestrictions.visibility = View.GONE
}
if (nativeAd.containsVideo()) {
nativeAdView.nativeMediaView = nativeMediaView
} else {
nativeMediaView.visibility = View.GONE
}
nativeAdView.titleView = tvTitle
nativeAdView.descriptionView = tvDescription
nativeAdView.ratingView = ratingBar
nativeAdView.callToActionView = ctaButton
nativeAdView.setNativeIconView(nativeIconView)
nativeAdView.providerView = providerView
nativeAdView.registerView(nativeAd)
nativeAdView.visibility = View.VISIBLE
}
fun unregisterViewForInteraction() {
nativeAdView.unregisterViewForInteraction()
}
}
companion object {
private const val DEFAULT_NATIVE_STEP = 5
private const val VIEW_HOLDER_NATIVE_AD_TYPE = 600
}
}
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.RatingBar;
import android.widget.TextView;
import com.appodeal.ads.Appodeal;
import com.appodeal.ads.NativeAd;
import com.appodeal.ads.NativeAdView;
import com.appodeal.ads.NativeCallbacks;
import com.appodeal.ads.NativeIconView;
import com.appodeal.ads.NativeMediaView;
import java.util.List;
/**
* Wrapper adapter to show Native Ad in recycler view with fixed step
*/
public class AppodealWrapperAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
implements NativeCallbacks {
private static final int DEFAULT_NATIVE_STEP = 5;
private static final int VIEW_HOLDER_NATIVE_AD_TYPE = 600;
private final RecyclerView.Adapter<RecyclerView.ViewHolder> userAdapter;
private int nativeStep = DEFAULT_NATIVE_STEP;
private final SparseArray<NativeAd> nativeAdList = new SparseArray<>();
/**
* @param userAdapter user adapter
* @param nativeStep step show {@link com.appodeal.ads.NativeAd}
*/
public AppodealWrapperAdapter(RecyclerView.Adapter<RecyclerView.ViewHolder> userAdapter, int nativeStep) {
this.userAdapter = userAdapter;
this.nativeStep = nativeStep + 1;
userAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged() {
super.onChanged();
notifyDataSetChanged();
fillListWithAd();
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
notifyDataSetChanged();
fillListWithAd();
}
});
Appodeal.setNativeCallbacks(this);
fillListWithAd();
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == VIEW_HOLDER_NATIVE_AD_TYPE) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.include_native_ads, parent, false);
return new NativeCustomAdViewHolder(view);
} else {
return userAdapter.onCreateViewHolder(parent, viewType);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (holder instanceof NativeCustomAdViewHolder) {
((NativeCustomAdViewHolder) holder).fillNative(nativeAdList.get(position));
} else {
userAdapter.onBindViewHolder(holder, getPositionInUserAdapter(position));
}
}
@Override
public int getItemCount() {
int resultCount = 0;
resultCount += getNativeAdsCount();
resultCount += getUserAdapterItemCount();
return resultCount;
}
@Override
public int getItemViewType(int position) {
if (isNativeAdPosition(position)) {
return VIEW_HOLDER_NATIVE_AD_TYPE;
} else {
return userAdapter.getItemViewType(getPositionInUserAdapter(position));
}
}
@Override
public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) {
super.onViewRecycled(holder);
if (holder instanceof NativeCustomAdViewHolder) {
((NativeCustomAdViewHolder) holder).unregisterViewForInteraction();
}
}
/**
* Destroy all used native ads
*/
public void destroyNativeAds() {
for (int i = 0; i < nativeAdList.size(); i++) {
NativeAd nativeAd = nativeAdList.valueAt(i);
nativeAd.destroy();
}
nativeAdList.clear();
}
@Override
public void onNativeLoaded() {
fillListWithAd();
}
@Override
public void onNativeFailedToLoad() {
}
@Override
public void onNativeShown(NativeAd nativeAd) {
}
@Override
public void onNativeShowFailed(NativeAd nativeAd) {
}
@Override
public void onNativeClicked(NativeAd nativeAd) {
}
@Override
public void onNativeExpired() {
}
/**
* @return count of loaded ads {@link com.appodeal.ads.NativeAd}
*/
private int getNativeAdsCount() {
return nativeAdList.size();
}
/**
* @return user items count
*/
private int getUserAdapterItemCount() {
if (userAdapter != null) {
return userAdapter.getItemCount();
}
return 0;
}
/**
* @param position index in wrapper adapter
* @return {@code true} if item by position is {@link com.appodeal.ads.NativeAd}
*/
private boolean isNativeAdPosition(int position) {
return nativeAdList.get(position) != null;
}
/**
* Method for searching position in user adapter
*
* @param position index in wrapper adapter
* @return index in user adapter
*/
private int getPositionInUserAdapter(int position) {
return position - Math.min(nativeAdList.size(), position / nativeStep);
}
/**
* Method for filling list with {@link com.appodeal.ads.NativeAd}
*/
private void fillListWithAd() {
int insertPosition = findNextAdPosition();
NativeAd nativeAd;
while (canUseThisPosition(insertPosition) && (nativeAd = getNativeAdItem()) != null) {
nativeAdList.put(insertPosition, nativeAd);
notifyItemInserted(insertPosition);
insertPosition = findNextAdPosition();
}
}
/**
* Get native ad item
*
* @return {@link com.appodeal.ads.NativeAd}
*/
@Nullable
private NativeAd getNativeAdItem() {
List<NativeAd> ads = Appodeal.getNativeAds(1);
return !ads.isEmpty() ? ads.get(0) : null;
}
/**
* Method for finding next position suitable for {@link com.appodeal.ads.NativeAd}
*
* @return position for next native ad view
*/
private int findNextAdPosition() {
if (nativeAdList.size() > 0) {
return nativeAdList.keyAt(nativeAdList.size() - 1) + nativeStep;
}
return nativeStep - 1;
}
/**
* @param position index in wrapper adapter
* @return {@code true} if you can add {@link com.appodeal.ads.NativeAd} to this position
*/
private boolean canUseThisPosition(int position) {
return nativeAdList.get(position) == null && getItemCount() > position;
}
/**
* View holder for create custom {@link com.appodeal.ads.native_ad.views.NativeAdView}
*/
static class NativeCustomAdViewHolder extends RecyclerView.ViewHolder {
private final NativeAdView nativeAdView;
private final TextView tvTitle;
private final TextView tvDescription;
private final RatingBar ratingBar;
private final Button ctaButton;
private final NativeIconView nativeIconView;
private final TextView tvAgeRestrictions;
private final NativeMediaView nativeMediaView;
private final FrameLayout providerViewContainer;
NativeCustomAdViewHolder(View itemView) {
super(itemView);
nativeAdView = itemView.findViewById(R.id.native_item);
tvTitle = itemView.findViewById(R.id.tv_title);
tvDescription = itemView.findViewById(R.id.tv_description);
ratingBar = itemView.findViewById(R.id.rb_rating);
ctaButton = itemView.findViewById(R.id.b_cta);
nativeIconView = itemView.findViewById(R.id.icon);
providerViewContainer = itemView.findViewById(R.id.provider_view);
tvAgeRestrictions = itemView.findViewById(R.id.tv_age_restriction);
nativeMediaView = itemView.findViewById(R.id.appodeal_media_view_content);
}
void fillNative(NativeAd nativeAd) {
tvTitle.setText(nativeAd.getTitle());
tvDescription.setText(nativeAd.getDescription());
if (nativeAd.getRating() == 0) {
ratingBar.setVisibility(View.INVISIBLE);
} else {
ratingBar.setVisibility(View.VISIBLE);
ratingBar.setRating(nativeAd.getRating());
ratingBar.setStepSize(0.1f);
}
ctaButton.setText(nativeAd.getCallToAction());
View providerView = nativeAd.getProviderView(nativeAdView.getContext());
if (providerView != null) {
if (providerView.getParent() != null && providerView.getParent() instanceof ViewGroup) {
((ViewGroup) providerView.getParent()).removeView(providerView);
}
providerViewContainer.removeAllViews();
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
providerViewContainer.addView(providerView, layoutParams);
}
if (nativeAd.getAgeRestrictions() != null) {
tvAgeRestrictions.setText(nativeAd.getAgeRestrictions());
tvAgeRestrictions.setVisibility(View.VISIBLE);
} else {
tvAgeRestrictions.setVisibility(View.GONE);
}
if (nativeAd.containsVideo()) {
nativeAdView.setNativeMediaView(nativeMediaView);
} else {
nativeMediaView.setVisibility(View.GONE);
}
nativeAdView.setTitleView(tvTitle);
nativeAdView.setDescriptionView(tvDescription);
nativeAdView.setRatingView(ratingBar);
nativeAdView.setCallToActionView(ctaButton);
nativeAdView.setNativeIconView(nativeIconView);
nativeAdView.setProviderView(providerView);
nativeAdView.registerView(nativeAd);
nativeAdView.setVisibility(View.VISIBLE);
}
void unregisterViewForInteraction() {
nativeAdView.unregisterViewForInteraction();
}
}
}
To use this wrapper adapter, you should create a new instance ofAppodealWrapperAdapter
:
- Kotlin
- Java
val appodealWrapperAdapter: AppodealWrapperAdapter = AppodealWrapperAdapter(myAdapter, 2)
AppodealWrapperAdapter appodealWrapperAdapter = new AppodealWrapperAdapter(myAdapter, 2);
And set this wrapper adapter to your recycler view.
Common Mistakes
- No ad attribution or AdChoices icon
The majority of ad networks require publishers to add a special mark to a native ad, so users don’t mistake them for content. That’s why you always need to make sure, that native ads in your app have the ad attribution (e.g., “Ad”) or the AdChoices icon.
- Absence of the required native ad elements
Every native ad should contain:
title;
call-to-action button;
ad attribution or AdChoices icon;
icon, image or video.
Native ad elements alteration
Advertisers expect that their ads will be displayed clearly and without any alteration. You can scale buttons and images, but you shouldn't crop, cover or distort them.
- Overlaying elements of native ads on each other
Make sure, that all elements of a native ad are visible and not overlaid.
Native ads requirements:
- All of the fields of native ad marked as mandatory must be displayed.
- Every ad should have a sign that clearly indicates that it is an ad. For example "Ad" or "Sponsored".
- Image assets can be resized to fit your ad space but should not be significantly distorted or cropped.
Check If Ad Is Initialized
To check if native was initialized, you can use the method:
- Kotlin
- Java
Appodeal.isInitialized(Appodeal.NATIVE)
Appodeal.isInitialized(Appodeal.NATIVE);
Returns true
, if the native was initialized.
Check If Autocache Is Enabled
To check if autocache is enabled for native, you can use the method:
- Kotlin
- Java
Appodeal.isAutoCacheEnabled(Appodeal.NATIVE)
Appodeal.isAutoCacheEnabled(Appodeal.NATIVE);
Returns true
, if autocache is enabled for native.
Get Predicted eCPM
To get the predicted eCPM from the next block in the caching queue, use the method:
- Kotlin
- Java
NativeAd.getPredictedEcpm()
NativeAd.getPredictedEcpm();
This method is reasonable to use if manual caching of ads is enabled.
Check Viewability
You can always check in logs if show was tracked and your ad is visible.
You will see the Native [Notify Shown] log if show was tracked successfully.
- Log
Appodeal com.example.app D Native [Notify Shown]