Shabab
Shabab

Reputation: 19

how to add ads in listview in MyAdapter

How can I add AdMob ads in a list view?

I just add MyAdapter class and MyViewHolder class but I get an error.

Here is my code:

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {

/// LIST ADS
private static final int MENU_ITEM_VIEW_TYP = 0;
private static final int AD_VIEW_TYPE = 1;
/// LIST ADS

Context c;
ArrayList<Article> articles;
public MyAdapter(Context c, ArrayList<Article> articles) {
    this.c = c;
    this.articles = articles;
}

public class NativeExpressAdsViewHoolder extends MyViewHolder {
    NativeExpressAdsViewHoolder(View view){
        super(view);
    }

}

@Override
public int getItemCount() {
    return articles.size();
}
@Override
public long getItemId(int position) {
    return (position % 8 == 0) ? AD_VIEW_TYPE: position;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
   switch (viewType) {
        case AD_VIEW_TYPE:
            View nativ = LayoutInflater.from(c).inflate(R.layout.native_expres_continer, parent, false);
            return new MyViewHolder(nativ);
       case MENU_ITEM_VIEW_TYP:
        default:

            View v = LayoutInflater.from(c).inflate(R.layout.model, parent, false);
            return new MyViewHolder(v);

    }


}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {

    Article article=articles.get(position);

    NativeExpressAdsViewHoolder nativeExpressHolder = (NativeExpressAdsViewHoolder)holder;
    NativeExpressAdView adsView = (NativeExpressAdView)articles.get(position);

    Article adview=articles.get(position);


    String title=article.getTitle();
    String desc=article.getDescription();
    String date=article.getDate();
   /// String imageUrl=article.getImageUrl();
    holder.titleTxt.setText(title);
    holder.desctxt.setText(desc);
    holder.dateTxt.setText(date);
   // PicassoClient.downloadImage(c,imageUrl,holder.img);
}

}

Myviewholder class

public class MyViewHolder extends RecyclerView.ViewHolder {
TextView titleTxt,desctxt,dateTxt,adview;
ImageView img;
public MyViewHolder(View itemView) {
    super(itemView);
    titleTxt= (TextView) itemView.findViewById(R.id.titleTxt);
    desctxt= (TextView) itemView.findViewById(R.id.descTxt);
    dateTxt= (TextView) itemView.findViewById(R.id.dateTxt);

   // img= (ImageView) itemView.findViewById(R.id.articleImage);
}

}

Upvotes: 2

Views: 48

Answers (1)

Daniel W.
Daniel W.

Reputation: 623

Without knowing the exact error you get I think the code might be problematic because of how you integrate the ads.

First you will never actually show all the articles actually in the list because you just say for every 8th article it should display an ad instead but the original 8th article in the list won't be shown.

Now I think where your example crashes is in onBindViewHolder at the 8th element when you actually try to access titleTxt, desctxt or dateTxt on it. The ViewHolder you inflated is a NativeExpressAdsViewHoolder (because it's also of type RecyclerView.ViewHolder <- btw you can leave that whole check. The holder of onBindViewHolder will always be a ViewHolder) so it won't have those fields and the program will crash.

In order for this to work you will need to have a representation for the ads available in the backing collection you supply to the Adapter.

So instead of giving your Adapter a list of articles I would introduce an interface like this:

interface ListElement {

    ElementType getType();

    enum ElementType {
        ARTICLE,
        AD
    }
}

Of course now your Article class will need to implement this interface and always statically return ElementType.ARTICLE in the getType method and you need an empty class Ad that also implements the interface and always returns ElementType.AD in its getType method.

Now I assume you load your articles somewhere from the web and then pass them to the Adapter? So now before passing them to the adapter you insert the Ad placeholder classes. So whereever you instanciate your Adapter do something like this:

private MyAdapter createAdapter(List<Article> articlesLoadedFromWeb) {
    final List<ListElement> articlesAndAds = new ArrayList<>();

    for (int i = 0; i < articlesLoadedFromWeb.size(); i++) {
        if (i % 8 == 0) {
            articlesAndAds.add(new Ad());
        } else {
            articlesAndAds.add(articlesLoadedFromWeb(i));
        }
    }

    return new MyAdapter(getContext(), articlesAndAds);
}

And then your Adapter could look like this:

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {


    final Context c;
    final List<ListElement> articlesAndAds;

    public MyAdapter(Context c, List<ListElement> articlesAndAds) {
        this.c = c;
        this.articlesAndAds = articlesAndAds;
    }

    public class NativeExpressAdsViewHolder extends MyViewHolder {
        NativeExpressAdsViewHolder(View view){
            super(view);
        }

    }

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

    @Override
    public long getItemId(int position) {
        return articlesAndAds.get(position).getType().ordinal();
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
       switch (viewType) {
            case ListElement.ElementType.AD.ordinal():
                View nativ = LayoutInflater.from(c).inflate(R.layout.native_express_container, parent, false);
                return new MyViewHolder(nativ);
           case ListElement.ElementType.ARTICLE.ordinal():
           default:

                View v = LayoutInflater.from(c).inflate(R.layout.model, parent, false);
                return new MyViewHolder(v);

        }

    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {

        if (articlesAndAds.get(position).getType() == ListElement.ElementType.ARTICLE) {
            final Article article = (Article) articles.get(position);

            String title = article.getTitle();
            String desc = article.getDescription();
            String date = article.getDate();
            /// String imageUrl = article.getImageUrl();
            holder.titleTxt.setText(title);
            holder.desctxt.setText(desc);
            holder.dateTxt.setText(date);
            // PicassoClient.downloadImage(c, imageUrl, holder.img);
        }
    }

}

Upvotes: 1

Related Questions