InMobi Native Ads support both static and video ads. You can opt for In-Feed, Splash, or Pre-Roll formats. The steps for creating a native ad placement are given below.
InMobi Native Ads support both static and video ads. You can opt for In-Feed, Splash , or Pre-Roll formats. The steps for creating a native ad placement are given below.
Once the native placement is created, you will be able to see the placement ID.

To create a native ad, create an InMobiNative instance:
public class NativeAdsActivity extends Activity {
……………………
private final List<InMobiNative> mNativeAds = new ArrayList<>();
……………………
InMobiNative nativeAd = new InMobiNative(NativeAdsActivity.this, YOUR_PLACEMENT_ID, nativeAdEventListener);
nativeAd.load();
mNativeAds.add(nativeAd);
……………………
}
class NativeAdsActivity : Activity {
……………………
private val mNativeAds : List<inmobinative> = ArrayList()
……………………
val nativeAd = InMobiNative(this@NativeAdsActivity, YOUR_PLACEMENT_ID, nativeAdEventListener)
nativeAd.load()
mNativeAds.add(nativeAd)
……………………
}
Here nativeAdEventListener is an implementation of the NativeAdEventListener abstract class. It is mandatory to supply an implementation of this interface to create a native ad. Creating an InMobiNative object without SDK Initialization will throw an exception.
You must supply a Context implementation to the InMobiNative constructor. Please make sure your implementation holds a strong reference of InMobiNative otherwise, you will not be able to get any callback from SDK for this reference. This can be achieved by making it a member variable of a class or storing it in the collection, which lives through your application life cycle.
inMobiNative should always be a strong reference otherwise, you may not receive any callback (load success, load failure, etc.) for this reference.inMobiNative is referenced by any variable, ensure that it is a strong reference.inMobiNative is not removed due to garbage collection.NativeAdEventListener abstract class allows you to listen to key lifecycle events for a native ad.
/**
* A listener for receiving notifications during the lifecycle of a Native ad.
*/
public abstract class NativeAdEventListener {
/**
* Called to indicate that an ad was loaded and it can now be shown. This will always be called
* after the {@link ##onAdReceived(InMobiNative)} callback.
*
* @param ad Represents the {@link InMobiNative} ad which was loaded
*/
public void onAdLoadSucceeded(InMobiNative ad) {}
/**
* Called to notify that a native ad failed to load.
*
* @param ad Represents the {@link InMobiNative} ad which failed to load
* @param requestStatus Represents the {@link InMobiAdRequestStatus} status containing error reason
*/
public void onAdLoadFailed(InMobiNative ad, InMobiAdRequestStatus requestStatus) {}
/**
*
* @param ad Represents the {@link InMobiNative} ad whose fullscreen was dismissed
*/
public void onAdFullScreenDismissed(InMobiNative ad) {}
/**
* Called to notify that the ad opened an overlay that covers the screen.
*
* @param ad Represents the {@link InMobiNative} ad whose fullscreen will be displayed
*/
public void onAdFullScreenDisplayed(InMobiNative ad) {}
/**
* Called to notify that the user is about to leave the application as a result of interacting with it.
*
* @param ad Represents the {@link InMobiNative} ad
*/
public void onUserWillLeaveApplication(InMobiNative ad) {}
/**
* Called to notify ad was clicked. Note:Override this method to notify click to the Mediation Adapter.
*
* @param ad Represents the {@link InMobiNative} ad which was clicked
*/
public void onAdClicked(InMobiNative ad) {}
/**
* Called to notify that inmobi has logged an impression for the ad
*
* @param ad Represents the ad which was impressed
*/
public void onAdImpression(@NonNull InMobiNative ad) {}
/**
* Called to notify that an ad was received successfully but is not ready to be displayed yet.
*
* @param ad Represents the ad which was loaded or preloaded
* @param info Represents the ad meta information
*/
public void onAdFetchSuccessful(@NonNull T ad, @NonNull AdMetaInfo info) {}
}
/**
* A listener for receiving notifications during the lifecycle of a Native ad.
*/
abstract class NativeAdEventListener : AdEventListener<InMobiNative>() {
/**
* @param ad Represents the [InMobiNative] ad whose fullscreen was dismissed
*/
open fun onAdFullScreenDismissed(ad: InMobiNative) {}
/**
* Called to notify that the ad opened an overlay that covers the screen.
*
* @param ad Represents the [InMobiNative] ad whose fullscreen will be displayed
*/
open fun onAdFullScreenDisplayed(ad: InMobiNative) {}
/**
* Called to notify that the user is about to leave the application as a result of interacting with it.
*
* @param ad Represents the [InMobiNative] ad
*/
open fun onUserWillLeaveApplication(ad: InMobiNative) {}
/**
* Called to notify ad was clicked. **Note:**Override this method to notify click to the Mediation Adapter.
*
* @param ad Represents the [InMobiNative] ad which was clicked
*/
open fun onAdClicked(ad: InMobiNative) {}
/**
* Called to notify that inmobi has logged an impression for the ad
* @param ad Represents the ad which was impressed
*/
open fun onAdImpression(ad: InMobiNative) {}
/**
* Called to notify that an ad was received successfully but is not ready to be displayed yet.
*
* @param ad Represents the ad which was loaded or preloaded
* @param info Represents the ad meta information
*/
fun onAdFetchSuccessful(ad: T,info: AdMetaInfog) {}
}
VideoEventListener abstract class allows you to listen to video lifecycle events for a native ad.
/**
* Listener interface for receiving video lifecycle and interaction events.
*
* This interface provides callbacks for various video playback states and user interactions
* with video advertisements. Implementers can use these events to track video performance,
* handle audio state changes, and respond to video playback lifecycle events for analytics
* and user experience optimization.
*/
interface VideoEventListener {
/**
* Called when video playback has started.
*
* This method is invoked when the video begins playing for the first time.
*/
public void onVideoStarted()
/**
* Called when video playback has resumed from a paused state.
*
* This method is invoked when the video continues playing after being paused.
*/
public void onVideoResumed()
/**
* Called when video playback has been paused.
*
* This method is invoked when the video is temporarily stopped by user action
* or programmatic control.
*/
public void onVideoPaused()
/**
* Called when video playback has completed successfully.
*
* This method is invoked when the video has played to its end.
*/
public void onVideoCompleted()
/**
* Called when the audio state of the video has changed.
*
* This method is invoked whenever the video's audio is muted or unmuted,
* allowing implementers to track audio interaction patterns.
*
* @param isMuted true if the video is currently muted, false if audio is enabled
*/
public void onAudioStateChanged(boolean isMuted)
}
/**
* Listener interface for receiving video lifecycle and interaction events.
*
* This interface provides callbacks for various video playback states and user interactions
* with video advertisements. Implementers can use these events to track video performance,
* handle audio state changes, and respond to video playback lifecycle events for analytics
* and user experience optimization.
*/
interface VideoEventListener {
/**
* Called when video playback has started.
*
* This method is invoked when the video begins playing for the first time.
*/
fun onVideoStarted()
/**
* Called when video playback has resumed from a paused state.
*
* This method is invoked when the video continues playing after being paused.
*/
fun onVideoResumed()
/**
* Called when video playback has been paused.
*
* This method is invoked when the video is temporarily stopped by user action
* or programmatic control.
*/
fun onVideoPaused()
/**
* Called when video playback has completed successfully.
*
* This method is invoked when the video has played to its end.
*/
fun onVideoCompleted()
/**
* Called when the audio state of the video has changed.
*
* This method is invoked whenever the video's audio is muted or unmuted,
* allowing implementers to track audio interaction patterns.
*
* @param isMuted true if the video is currently muted, false if audio is enabled
*/
fun onAudioStateChanged(isMuted: Boolean)
}
To request a native ad, call the load() method on the InMobiNative instance you created above:
nativeAd.load();
nativeAd.load()
The NativeAdEventListener abstract class notifies the result of this method. If the ad request was successful, the onAdReceived(InMobiNative) event is generated. This is followed by either the onAdLoadSucceeded or the onAdLoadFailed event. If the onAdLoadFailed event is generated, the reason is indicated by the InMobiAdRequestStatus object passed in this event.
To receive video events register videoEventListener using method setVideoEventListener (VideoEventListener videoEventListener) on the InMobiNative instance you created above:
nativeAd.setVideoEventListener (videoEventListener);
nativeAd.setVideoEventListener (videoEventListener)
The VideoEventListener abstract class notifies you about video events for native ads.
Here are some important APIs in InMobiNative that will help to stitch the ads:
String getAdTitle() - Returns the title text for the ad.String getAdDescription() - Returns the description text for the ad.AdAsset getAdIcon() - Returns the icon asset object. Use getAdIcon().url to get the icon image URL.String getCtaText() - Returns the call-to-action text for the ad.Float getAdRating() - Returns the rating for the ad (optional, returns 0 if not available).String getAdvertiserName() - Returns the advertiser/sponsored name for the ad.View getMediaView() - Returns the media view containing the ad's image or video content. This should be added to your media container (FrameLayout).View getAdChoiceIcon() - Returns the AdChoices icon view. This should be added to your AdChoices container.boolean isReady() - Returns true when the ad is ready to be displayed.Boolean isVideo() - Returns true if the ad contains video content, false otherwise, or null if called in an invalid state.void registerViewForTracking(InMobiNativeViewData viewData) - Registers your custom ad views with the InMobi SDK for impression tracking and click handling. This is a critical step that:
To register views, use the InMobiNativeViewData.Builder class:
InMobiNativeViewData nativeViewData = new InMobiNativeViewData.Builder(adViewContainer)
.setIconView(iconImageView)
.setTitleView(titleTextView)
.setDescriptionView(descriptionTextView)
.setCTAView(ctaButton)
.setRatingView(ratingBar)
.setExtraViews(Arrays.asList(sponsoredTextView))
.build();
nativeAd.registerViewForTracking(nativeViewData);
val nativeViewData = InMobiNativeViewData.Builder(adViewContainer)
.setIconView(iconImageView)
.setTitleView(titleTextView)
.setDescriptionView(descriptionTextView)
.setCTAView(ctaButton)
.setRatingView(ratingBar)
.setExtraViews(Arrays.asList(sponsoredTextView))
.build()
nativeAd.registerViewForTracking(nativeViewData)
JSONObject getCustomAdContent() - Returns a JSONObject containing additional information (description, image URL, etc.) for custom UI implementations.A native ad can be stitched in your app in three formats:
For example, to show ad at 4th position:
private static final int AD_POSITION = 4;
private val AD_POSITION = 4
If the ad load is successful, you will get a callback onAdLoadSucceeded(InMobiNative).You should then add the InMobiNativeAd object to your data source within this listener. If your feed in the app is a ListView, a sample implementation for ListView is shown below:
@Override
public void onAdLoadSucceeded(@NonNull InMobiNative nativeAd) {
AdFeedItem nativeAdFeedItem = new AdFeedItem(nativeAd);
mFeedItems.add(AD_POSITION, nativeAdFeedItem);
mFeedAdapter.notifyDataSetChanged();
}
override fun onAdLoadSucceeded(nativeAd: InMobiNative) {
val nativeAdFeedItem = AdFeedItem(nativeAd)
mFeedItems.add(AD_POSITION, nativeAdFeedItem)
mFeedAdapter.notifyDataSetChanged()
}
AdFeedItem is an extension class of your FeedItem class, where FeedItem is the class which powers each row of your ListView. Also mItems is the ArrayList, which powers the Adapter of this ListView.So far, we have loaded an ad and added it to your data source. Now, it’s time to display the ad. The sample implementation for ListView is as follows:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final int itemViewType = getItemViewType(position);
if (itemViewType == VIEW_TYPE_CONTENT_FEED) {
//Your app code
} else {
//Since this content type is InMobi Ad, you need to get native Ad view
final InMobiNative nativeAd = ((AdFeedItem) feedItem).mNativeAd;
parent, parent.getWidth());
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.ad_item, parent, false);
}
// Get view references
ImageView icon = convertView.findViewById(R.id.adIcon);
TextView title = convertView.findViewById(R.id.adTitle);
TextView description = convertView.findViewById(R.id.adDescription);
Button cta = convertView.findViewById(R.id.adAction);
FrameLayout mediaContainer = convertView.findViewById(R.id.adContent);
RatingBar ratingBar = convertView.findViewById(R.id.adRating);
TextView sponsored = convertView.findViewById(R.id.adSponsored);
FrameLayout adChoice = convertView.findViewById(R.id.adChoice);
// Populate text views
title.setText(nativeAd.getAdTitle());
description.setText(nativeAd.getAdDescription());
cta.setText(nativeAd.getCtaText());
sponsored.setText(nativeAd.getAdvertiserName());
// Load icon using your preferred image loading library (e.g., Picasso, Glide)
if (nativeAd.getAdIcon() != null) {
Picasso.get().load(nativeAd.getAdIcon().getUrl()).into(icon);
}
// Add media view
mediaContainer.removeAllViews();
if (nativeAd.getMediaView() != null) {
// Remove from previous parent if attached
ViewGroup mediaParent = (ViewGroup) nativeAd.getMediaView().getParent();
if (mediaParent != null) {
mediaParent.removeAllViews();
}
mediaContainer.addView(nativeAd.getMediaView());
}
// Set rating if available
float rating = nativeAd.getAdRating();
if (rating > 0) {
ratingBar.setRating(rating);
ratingBar.setVisibility(View.VISIBLE);
} else {
ratingBar.setVisibility(View.GONE);
}
// Add AdChoice icon
adChoice.removeAllViews();
if (nativeAd.getAdChoiceIcon() != null) {
ViewGroup adChoiceParent = (ViewGroup) nativeAd.getAdChoiceIcon().getParent();
if (adChoiceParent != null) {
adChoiceParent.removeAllViews();
}
adChoice.addView(nativeAd.getAdChoiceIcon());
}
// CRITICAL: Register views for tracking (Native 2.0)
InMobiNativeViewData nativeViewData = new InMobiNativeViewData.Builder((ViewGroup) convertView)
.setIconView(icon)
.setTitleView(title)
.setDescriptionView(description)
.setCTAView(cta)
.setRatingView(ratingBar)
.setExtraViews(Arrays.asList(sponsored))
.build();
nativeAd.registerViewForTracking(nativeViewData);
return convertView;
}
}
override fun getView(position: Int, convertViewParam: View?, parent: ViewGroup): View {
val itemViewType = getItemViewType(position)
if (itemViewType == VIEW_TYPE_CONTENT_FEED) {
// Your app code
return convertViewParam ?: View(parent.context) // Placeholder return, adjust as needed
} else {
// Since this content type is InMobi Ad, you need to get native Ad view
val feedItem = getItem(position) // Assuming getItem method exists and returns the feed item
val nativeAd = (feedItem as AdFeedItem).mNativeAd
var convertView = convertViewParam
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.ad_item, parent, false)
}
// Get view references
val icon = convertView.findViewById(R.id.adIcon)
val title = convertView.findViewById(R.id.adTitle)
val description = convertView.findViewById(R.id.adDescription)
val cta = convertView.findViewById(R.id.adAction)
val mediaContainer = convertView.findViewById(R.id.adContent)
val ratingBar = convertView.findViewById(R.id.adRating)
val sponsored = convertView.findViewById(R.id.adSponsored)
val adChoice = convertView.findViewById(R.id.adChoice)
// Populate text views
title.text = nativeAd.adTitle
description.text = nativeAd.adDescription
cta.text = nativeAd.ctaText
sponsored.text = nativeAd.advertiserName
// Load icon using your preferred image loading library (e.g., Picasso, Glide)
nativeAd.adIcon?.url?.let { url ->
Picasso.get().load(url).into(icon)
}
// Add media view
mediaContainer.removeAllViews()
nativeAd.mediaView?.let { mediaView ->
(mediaView.parent as? ViewGroup)?.removeAllViews()
mediaContainer.addView(mediaView)
}
// Set rating if available
val rating = nativeAd.adRating
if (rating > 0) {
ratingBar.rating = rating
ratingBar.visibility = View.VISIBLE
} else {
ratingBar.visibility = View.GONE
}
// Add AdChoice icon
adChoice.removeAllViews()
nativeAd.adChoiceIcon?.let { adChoiceIcon ->
(adChoiceIcon.parent as? ViewGroup)?.removeAllViews()
adChoice.addView(adChoiceIcon)
}
// CRITICAL: Register views for tracking (Native 2.0)
val nativeViewData = InMobiNativeViewData.Builder(convertView as ViewGroup)
.setIconView(icon)
.setTitleView(title)
.setDescriptionView(description)
.setCTAView(cta)
.setRatingView(ratingBar)
.setExtraViews(listOf(sponsored))
.build()
nativeAd.registerViewForTracking(nativeViewData)
return convertView
}
}
The function getItemViewType(position) checks whether the content type is FEED OR AD as given below:
@Override
public int getItemViewType(int position) {
FeedItem feedItem = getItem(position);
if (feedItem instanceof AdFeedItem) {
return VIEW_TYPE_INMOBI_STRAND;
}
return VIEW_TYPE_CONTENT_FEED;
}
override fun getItemViewType(position: Int): Int {
val feedItem: FeedItem = getItem(position)
return if (feedItem is AdFeedItem) {
VIEW_TYPE_INMOBI_STRAND
} else VIEW_TYPE_CONTENT_FEED
}
Splash experience can be implemented using the same InMobiNative class. However, there are a few things to be noted:
InMobiNativeAd.isReady() function to determine if the ad is ready to be shown. Sometimes, your main thread may be occupied and hence you may not receive onAdLoadSucceeded in time. Hence, it is better to proactively check if the ad is ready just after your cut-off time has elapsed.onAdFullScreenDisplayed and not dismiss the ad if this callback is fired.A sample implementation is as follows:
@Override
public void onAdFullScreenDisplayed(InMobiNative nativeAd) {
isSecondScreenDisplayed = YES;
}
public void dismissAd() {
if (isSecondScreenDisplayed) {
Log.d(TAG, "DO NOT DISMISS THE AD WHILE THE SCREEN IS BEING DISPLAYED");
} else {
splashAdView.setVisibility(View.GONE);
nativeAd.destroy();
}
}
override fun onAdFullScreenDisplayed(nativeAd: InMobiNative?) {
isSecondScreenDisplayed = YES
}
fun dismissAd() {
if (isSecondScreenDisplayed) {
Log.d(TAG, "DO NOT DISMISS THE AD WHILE THE SCREEN IS BEING DISPLAYED")
} else {
splashAdView.setVisibility(View.GONE)
nativeAd.destroy()
}
}
Pre-Roll Video experience can be implemented using the same InMobiNative Class. You need to register videoEventListener and need to dismiss the ad view in the following callback:
@Override
public void onVideoCompleted(@NonNull InMobiNative nativeAd) {
Log.d (TAG, "Media playback complete " + mPosition);
}
override fun onVideoCompleted(@NonNull nativeAd: InMobiNative?) {
Log.d(TAG, "Media playback complete $mPosition")
}
The Pre-Roll ad can be dismissed as follows:
public void dismissAd() {
plashAdView.setVisibility(View.GONE);
nativeAd.destroy();
}
fun dismissAd() {
plashAdView.setVisibility(View.GONE)
nativeAd.destroy()
}
public void onAdLoadSucceeded(@NonNull <inmobi_ad_object> ad, @NonNull AdMetaInfo info) { Log.d(TAG, “Creative ID for ad : “ + info.getCreativeID()); }
fun onAdLoadSucceeded(ad:<inmobi_ad_object> , info:AdMetaInfo ) {
Log.d(TAG, “Creative ID for ad : “ + info.getCreativeID())
}
You will need to refresh the ad at various points to optimize ad exposure to your users. To refresh the ad, you will need to call the following functions in the exact order.
It is important to remove the adFeedItem object from your data source and destroying it before refreshing. You will then need to create a new object and call load as shown in the following code:
private void refreshAd() {
Iterator < FeedItems > feedItemIterator = mFeedItems.iterator();
while (feedItemIterator.hasNext()) {
final FeedItem feedItem = feedItemIterator.next();
if (feedItem instanceof AdFeedItem) {
feedItemIterator.remove();
}
}
// refresh feed
mFeedAdapter.notifyDataSetChanged();
// destroy InMobiNative object
inMobiNativeAd.destroy();
// create InMobiNative object again
InMobiNative inMobiNativeAd = new InMobiNative(
<< Activity Instance >> ,
<< Your Placement ID >> ,
<< InMobiNativeAdListener created in step 1 >> );
inMobiNativeAd.load();
}
private fun refreshAd() {
val feedItemIterator = mFeedItems.iterator()
while (feedItemIterator.hasNext()) {
val feedItem = feedItemIterator.next()
if (feedItem instanceof AdFeedItem) {
feedItemIterator.remove()
}
}
// refresh feed
mFeedAdapter.notifyDataSetChanged()
// destroy InMobiNative object
inMobiNativeAd.destroy()
// create InMobiNative object again
InMobiNative inMobiNativeAd = new InMobiNative(
<< Activity Instance >> ,
<< Your Placement ID >> ,
<< InMobiNativeAdListener created in step 1 >>
);
inMobiNativeAd.load()
}
InMobiNative represents exactly one ad.InMobiNative as the number of ad positions.InMobiNative in onCreate() callback of Activity or in onActivityCreated() callback of Fragment.InMobiNative instances in onDestroy() callback of Activity or in OnDestroyView() callback of Fragment.InMobiNativeAd object must always be destroyed once you remove it from the data source. All user interactions with the ad view will not be honored after InMobiNativeAd is destroyed. So, you will have to definitely discard the ad view before destroying the InMobiNativeAd.InMobiNativeAd instances must also be destroyed, when the component hosting them (your activity in this case) is getting destroyed using the destroy() API.By installing this SDK update, you agree that your Children Privacy Compliance setting remains accurate or that you will update that setting, whenever there is a change in your app's audience. You may update the app's Children Privacy Compliance settings at https://publisher.inmobi.com/my-inventory/app-and-placements.