Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can display an AdView at every n-th position in a listView

I have the code below which works except it always hides atleast one real item in the listview because the ad displays at that position.

Example of the problem: I have a list of 4 times, and the adView is displaying at position 3. on the listview I can only see 3 times and the AdView, the 4th item does not get displayed

I played around with increasing the size of the adapter everytime I return an ad but it didn't work very well.

Any ideas?

public View getView(final int position, View row, ViewGroup parent) {
        MyHolder holder = null;
        boolean showAd = proVersion == false && (position % 8 == k);
        if (showAd) {
            AdView adView = adList.get(position);
            if (adView == null) {
                AdView adViewNew = new AdView((Activity) context, AdSize.BANNER, context.getResources().getString(
                        R.string.adId));
                adViewNew.loadAd(Utils.getAdRequest("gps", lat, lng, keywords));
                adList.add(position, adViewNew);
                return adViewNew;
            } else {
                return adView;
            }
        } else if (row == null || row instanceof AdView) {
            LayoutInflater inflater = ((SherlockActivity) context).getLayoutInflater();
            row = inflater.inflate(viewResourceId, parent, false);
            holder = new MyHolder();
            holder.textName = (TextView) row.findViewById(R.id.name);           
            row.setTag(holder);
        } else {
            holder = (MyHolder) row.getTag();
        }
        holder.textName.setText(items.get(position).getName());

        // more code

        return row;
    }

    @Override
    public int getCount() {
        if (items != null) {
            return items.size();
        } else {
            return 0;
        }
    }
like image 768
code511788465541441 Avatar asked Dec 20 '22 17:12

code511788465541441


1 Answers

There is more than one way of achieving this. The best way is relying upon the ability of the listView to recycle multiple item types.

In your adapter,

  1. getViewTypeCount() - returns information how many types of rows you have in the listView
  2. getItemViewType(int position) returns information on which layout type you should use based on the position. That's where your logic of determining the listView objects should go.

There is a good tutorial on how to use different item types in a list here: Specifically, look at "Different list items’ layouts".

After that, you need minor arithmetic conversions for your indices so that you map the position to the right place in your data structure (or, you can merge your data structure to include both ad data and item data).

Basically, instead of using items.size() you need to use items.size() + Math.floor(items.size()/NTH_ITEM) and when you get the position, if it's an ad position (position % NTH_ITEM == 0) use a simple conversion like Math.floor(position/NTH_ITEM) to extract from the ad data structure and in similar fashion for your item's structure.

You should rely on the holder pattern of the ListView to reuse your different item view types, like in the tutorial above.

Different approaches, just for the notion, include using something like item wrappers that merge the data source into one and enables differentiating between items by using a type property, like an enum, or a "merging adapter" that merges two specific adapters (this might have a better modularity if you are to include these view types in different lists).

Let me know if you need any help implementing specific parts of this in your use case.

like image 87
Ben Max Rubinstein Avatar answered Dec 22 '22 07:12

Ben Max Rubinstein