Advertisements can be really annoying if not properly displayed. Nobody likes such ads. And as a developer, it’s your responsibility that the ads in your app look attractive thereby increasing the engagement with users. We include an ad in our app with the intention of earning money. If no one is going to click on the ads, then all the expectations of earning from the app and the endless hours that we toiled for development of the app will go in vain. And this is the last thing that we want to happen.

 

Admob Native Ads is an ad format that gives developers the freedom to customize the look of their ad and match it with the overall design of the app. Today in this tutorial, I will show you how to add Native ads in RecyclerView. 

Go to Admob and sign in or create a new account and fill in the required details. Once done, select apps tab and click on Add Your First App.

Add app to Admob

Then, you will be asked to select whether you have already published your app on Play Store or not. Select yes or no. I selected no as I am creating a demo app. Now enter your app name and select Android as a platform. Click on Add.

Add app to Admob

Now copy the App ID as you will need it later. Click on Create Ad Unit and then select Native.

Native Ad Admob

Click on Get Started and then select Medium. Choose the template that you like and then edit the template that best fits your app design. Click on Validate Style to check if your ad meets the guidelines. You can always come back and edit this template.

Native Ad Template

Scroll down and enter a custom refresh rate of 30 seconds. Give your ad unit a name and click save. You will be shown some instructions along with your App and Ad Unit ID. Copy and store this ID somewhere as we will need it later. Click on Done.

 

For the demo, we will create a RecylcerView Activity integrated with Native Ads. To use support libraries starting from version 26.0.0, we need to add Google’s Maven repository to our project’s build.gradle file as described below: 

allprojects {
        repositories {
            jcenter()
            maven {
                url "https://maven.google.com"
            }
        }
    }

Add the Internet permission in the manifest file (Required for showing ads).

<uses-permission android:name="android.permission.INTERNET"/>

In order to use RecyclerView along with CardView, we need to add support design and CardView library. Also for showing images, we will be using Picasso library and CircleImageView library which will help us to make Images circular. We also need to add Admob dependency for showing ads. Add the below dependencies in your app level build.gradle file:

compile 'com.android.support:design:26.0.2'
compile 'com.android.support:cardview-v7:26.0.2'
compile 'com.squareup.picasso:picasso:2.5.2'
compile 'de.hdodenhof:circleimageview:2.1.0'
compile 'com.google.android.gms:play-services-ads:11.2.0'

Now add the RecyclerView code to your activity_main.xml file.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical" />

</RelativeLayout>

We will be showing image, name and details of User in each row of RecyclerView so create a file named User.java as shown below:

public class User {

    String name, details;
    int imageId;

    public User() {
    }

    public User(String name, String details, int imageId) {
        this.name = name;
        this.details = details;
        this.imageId = imageId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDetails() {
        return details;
    }

    public void setDetails(String details) {
        this.details = details;
    }

    public int getImageId() {
        return imageId;
    }

    public void setImageId(int imageId) {
        this.imageId = imageId;
    }
}

Let’s create an XML file that will be responsible for how each row in a RecyclerView will appear. Create a file named row_item_user.xml

row_item_user.xml

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cardView"
    android:layout_width="match_parent"
    android:layout_height="150dp"
    android:layout_gravity="center"
    android:layout_marginBottom="8dp"
    android:layout_marginTop="8dp"
    card_view:cardCornerRadius="4dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical">

        <de.hdodenhof.circleimageview.CircleImageView
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/userProfile"
            android:layout_width="100dp"
            android:layout_height="100dp"
            app:civ_border_color="#FF000000"
            app:civ_border_width="1dp"
            android:layout_marginTop="25dp"
            android:layout_marginBottom="25dp"
            android:layout_marginLeft="8dp"
            />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:orientation="vertical"
            android:layout_toRightOf="@id/userProfile"
            android:padding="8dp">

            <TextView
                android:id="@+id/userName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="#000000"
                android:textSize="16sp"/>

            <TextView
                android:id="@+id/userDetails"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </RelativeLayout>
</android.support.v7.widget.CardView>

Since we are using Native ads, we can also control how AdView looks. Create a file named native_ad_row_type.xml

native_ad_row_type.xml

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/cvAds"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:layout_marginBottom="10dp"
    card_view:cardCornerRadius="@dimen/cardview_default_radius"
    card_view:cardElevation="@dimen/cardview_default_elevation" >

</android.support.v7.widget.CardView>

Now, let’s create the adapter for RecyclerView. Create a class named RecyclerViewAdapter and add the below code.

RecyclerViewAdapter.java

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.android.gms.ads.NativeExpressAdView;
import com.squareup.picasso.Picasso;


import java.util.List;

/**
 * Created by tecstaff on 10/09/17.
 */

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private static final int ITEM_VIEW_TYPE = 0;
    private static final int AD_VIEW_TYPE = 1;


    Context mContext;

    // The list of Native ads and recylcerview items.
    private final List<Object> mRecyclerViewItems;

    public RecyclerViewAdapter(Context context, List<Object> recyclerViewItems) {

        this.mContext = context;
        this.mRecyclerViewItems = recyclerViewItems;
    }

    //ViewHolder for binding User view
    public class MyViewHolder extends RecyclerView.ViewHolder {

        public TextView userName;
        public TextView userDetails;
        public ImageView userPic;

        public MyViewHolder(View view) {
            super(view);
            userName = (TextView) view.findViewById(R.id.userName);
            userDetails = (TextView) view.findViewById(R.id.userDetails);
            userPic = (ImageView) view.findViewById(R.id.userProfile);
        }
    }

    //ViewHolder for binding ad view
    public class NativeExpressAdViewHolder extends RecyclerView.ViewHolder {

        public NativeExpressAdViewHolder(View itemView) {
            super(itemView);
        }
    }


    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        //inflates adview or simple item view depending on the position of view
        switch (viewType) {

            case ITEM_VIEW_TYPE:
                View itemView = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.row_item_user, parent, false);
                return new MyViewHolder(itemView);

            case AD_VIEW_TYPE:
            default:
                View nativeExpressLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.native_ad_row_type, parent, false);
                return new NativeExpressAdViewHolder(nativeExpressLayoutView);


        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        int viewType = getItemViewType(position);

        switch (viewType) {

            case ITEM_VIEW_TYPE:

                MyViewHolder myViewHolder = (MyViewHolder) holder;
                final User user = (User) mRecyclerViewItems.get(position);

                //set name and detail of user
                myViewHolder.userName.setText(user.getName());
                myViewHolder.userDetails.setText(user.getDetails());

                //set the photo of user
                Picasso.with(((MyViewHolder) holder).userPic.getContext()).load(user.getImageId()).into(myViewHolder.userPic);


                break;

            case AD_VIEW_TYPE:
            default:
                NativeExpressAdViewHolder nativeExpressHolder = (NativeExpressAdViewHolder) holder;
                NativeExpressAdView adView = (NativeExpressAdView) mRecyclerViewItems.get(position);
                ViewGroup adCardView = (ViewGroup) nativeExpressHolder.itemView;
                adCardView.removeAllViews();

                if (adCardView.getChildCount() > 0) {
                    adCardView.removeAllViews();
                }
                if (adView.getParent() != null) {
                    ((ViewGroup) adView.getParent()).removeView(adView);
                }

                adCardView.addView(adView);

        }
    }

    @Override
    public int getItemCount() {
        return mRecyclerViewItems.size();
    }

    @Override
    public int getItemViewType(int position) {
        
        //the number 4 indicates that ad will be shown at every 4th position.
        // You can change it to whatever you like but also make sure to change it in your activity
        
        return (position % 4 == 0) ? AD_VIEW_TYPE : ITEM_VIEW_TYPE;
    }
}

Everything is setup now and it’s time to bind RecylerView and add some dummy User data to RecyclerView. Open your MainActivity.java file and add the below code:

MainActivity.java

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;

import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.NativeExpressAdView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    RecyclerView recyclerView;
    RecyclerView.Adapter adapter;
    private List<Object> mRecyclerViewItems = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MobileAds.initialize(this, getString(R.string.app_id)); //app id

        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);

        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());

        addUser();

        //setup and load native ads
        addNativeExpressAds();
        setUpAndLoadNativeExpressAds();

        adapter = new RecyclerViewAdapter(this, mRecyclerViewItems);
        recyclerView.setAdapter(adapter);

    }

    private void addUser() {

        //make sure add the images of user you want to show in drawable folder.

        User user = new User("James Anderson", "He is a very good bowler from England.", R.drawable.user1);
        mRecyclerViewItems.add(user);

        User user1 = new User("Johnny Depp", "One of the most paid actor in Hollywood.", R.drawable.user2);
        mRecyclerViewItems.add(user1);

        User user2 = new User("Elon Musk", "Inspiration for everyone. Also known as the living Iron Man.", R.drawable.user3);
        mRecyclerViewItems.add(user2);

        User user3 = new User("MKBHD", "Most followed tech YouTuber. Recently his channel crossed 5 million subscribers.", R.drawable.user4);
        mRecyclerViewItems.add(user3);

        User user4 = new User("Mrwhosetheboss", "Another tech YouTuber but a different one. Produces some great qualtiy content.", R.drawable.user1);
        mRecyclerViewItems.add(user4);

        User user5 = new User("Ravi Tamada", "Authour of a famous Android development blog AndroidHive.", R.drawable.user2);
        mRecyclerViewItems.add(user5);

        User user6 = new User("Mohit Gaur", "A singer from India who sings songs by including a story in them.", R.drawable.user3);
        mRecyclerViewItems.add(user6);

        User user7 = new User("Honey Singh", "Rapper from India known for many of his cool songs.", R.drawable.user4);
        mRecyclerViewItems.add(user7);

        User user8 = new User("Unerase Poetry", "A beautiful channel where you can find the youths of India presenting their poetry.", R.drawable.user1);
        mRecyclerViewItems.add(user8);

        User user9 = new User("Silicon Valley", "A series based on startup along with some comedy.", R.drawable.user2);
        mRecyclerViewItems.add(user9);

        User user10 = new User("Tyrion Lannister", "I think this man doesn't need an introduction.", R.drawable.user3);
        mRecyclerViewItems.add(user10);

        User user11 = new User("Jamie Lannister", "Brother of Tyrion Lannister.", R.drawable.user4);
        mRecyclerViewItems.add(user11);

        User user12 = new User("Jon Snow", "The one who doesn't know anything.", R.drawable.user1);
        mRecyclerViewItems.add(user12);

        User user13 = new User("Arya Stark", "The faceless girl from Game of Thrones.", R.drawable.user2);
        mRecyclerViewItems.add(user13);

     }

    private void addNativeExpressAds() {

        for (int i = 0; i < mRecyclerViewItems.size(); i += 4) {

            // Check whether we already have a NativeExpressAdView on the list before adding one
            if ((mRecyclerViewItems.size() - i == 0) || !(mRecyclerViewItems.get(i) instanceof NativeExpressAdView)) {
                final NativeExpressAdView adView = new NativeExpressAdView(this);
                mRecyclerViewItems.add(i, adView);
            }

        }
    }

    private void setUpAndLoadNativeExpressAds() {

        recyclerView.post(new Runnable() {
            @Override
            public void run() {
                final float density = getResources().getDisplayMetrics().density;
                // Set the ad size and ad unit ID for each Native Express ad in the items list.
                for (int i = 0; i <= mRecyclerViewItems.size(); i += 4) {
                    final NativeExpressAdView adView =
                            (NativeExpressAdView) mRecyclerViewItems.get(i);

                    // Since you can only set the AdSize AND an AdUnitID once per AdView
                    if (adView.getAdSize() == null) {
                        AdSize adSize = new AdSize(
                                (int) (recyclerView.getWidth() / density),
                                150);
                        adView.setAdSize(adSize);
                        adView.setAdUnitId(getString(R.string.ad_id);
                    }

                }

                // Load the first Native Express ad in the items list.
                loadNativeExpressAd(0);
            }
        });
    }

    /**
     * Loads the Native Express ads in the items list.
     */
    private void loadNativeExpressAd(final int index) {

        if (index >= mRecyclerViewItems.size()) {
            return;
        }

        Object item = mRecyclerViewItems.get(index);
        if (!(item instanceof NativeExpressAdView)) {
            throw new ClassCastException("Expected item at index " + index + " to be a Native"
                    + " Express ad.");
        }

        final NativeExpressAdView adView = (NativeExpressAdView) item;

        // Set an AdListener on the NativeExpressAdView to wait for the previous Native Express ad
        // to finish loading before loading the next ad in the items list.
        adView.setAdListener(new AdListener() {
            @Override
            public void onAdLoaded() {
                super.onAdLoaded();
                // The previous Native Express ad loaded successfully, call this method again to
                // load the next ad in the items list.
                loadNativeExpressAd(index + 4);
            }

            @Override
            public void onAdFailedToLoad(int errorCode) {
                // The previous Native Express ad failed to load. Call this method again to load
                // the next ad in the items list.
                Log.e("MainActivity", "The previous Native Express ad failed to load. Attempting to"
                        + " load the next Native Express ad in the items list.");
                loadNativeExpressAd(index + 4);
            }
        });


        // Load the Native Express ad.
        adView.loadAd(new AdRequest.Builder().build());
    }
}

Now when you run the app, you can see that native ads are loaded in RecyclerView as shown below.

If you face any difficulties, write it in the comment section and do share the article if you like it.

Download APK                                 View on Github

 

Categories: AndroidTutorials

  • shobhan

    how to avoid loading the ad for the first index for the same example ?

Related Posts

Android

Add Phone Number Authentication in Android (Firebase Tutorial #5)

This tutorial shows how to add Phone Number Authentication in Android app using Firebase. We have used FirebaseUI library for achieving authentication.

Android

Add Shimmer Effect to Android app

Rather than the same old circular loader, you can add shimmer effect to Android app when it is loading. This tutorial shows how you can add shimmer effect to your Android app.

Android

Upload an Image to Firebase Storage (Firebase Tutorial #4)

Today, I am going to show you how to upload an image to Firebase storage and then show that uploaded image in an ImageView in Android.

Subscribe and get a free eBook on 8 Tips to level up your Android Development Skills.

(We hate spam as much as you do)

You have Successfully Subscribed!

%d bloggers like this: