Reputation: 1751
I have a ListView that is populated by an ArrayAdapter, and I need to insert an advertisement after every Nth legitimate list item. The easiest way I can think of to do this would be to modify the array that defines the adapter's data set directly (or indirectly, via ArrayAdapter::add/insert) as follows:
/**
* Injects ad entries into the station list after every N legit entries
*
* @param adapter the arrayadapter that will generate the views representing our legit and ad list items
*/
private void injectAdEntries(MyArrayAdapter adapter){
int legitItemCount = adapter.getCount();
int adStride = 4;
if(legitItemCount >= adStride) {
//adstride-1 to account for the 0 index
for (int legitItemIndex = adStride-1; legitItemIndex < legitItemCount; legitItemIndex += adStride) {
//create clone of last legit entry, to use as context
// data for the ad, and mark it 'illegitimate' (ad)
LegitObject totallyLegit = new LegitObject(adapter.getItem(legitItemIndex));
totallyLegit.setLegit(false);
adapter.insert(totallyLegit,legitItemIndex+1);
}
}
}
After the injection, MyArrayAdapter's getView override can detect the false legit value and handle advertisement entries differently from legitimate entries.
The trouble is that I don't want to pollute the legitimate data array. Ideally, I would insert these advertisement list items without modifying the underlying data set in any way. Is there a way to make an adapter produce views that aren't reflected in its data set?
Edit
I also need all the items in the legitimate data set to be displayed in the ListView; the ad list items need to appear 'in addition to' rather than 'instead of' legitimate list items.
Upvotes: 0
Views: 109
Reputation: 1663
I will assume that you are using a recyclerView as a list. So, to have heterogenous layouts (i.e.: YOUR ACTUAL ITEM LAYOUT + AD LAYOUT) you should follow these steps:
Override getItemView
like
@Override
public int getItemViewType(int position) {
// insert an Ad every multiple of 5
if (position % 5 == 0) {
return AD_POSITION;
}
return NORMAL_POSITION;
}
Next, you need to override the onCreateViewHolder
method to tell the RecyclerView.Adapter
about which RecyclerView.ViewHolder
object to create based on the viewType
returned.
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
RecyclerView.ViewHolder viewHolder;
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
switch (viewType) {
case AD_POSITION:
View v1 = inflater.inflate(R.layout.list_item_ad, viewGroup, false);
viewHolder = new AdViewHolder(v1);
break;
default:
// NORMAL_POSITION
View v = inflater.inflate(R.layout.list_item, viewGroup, false);
viewHolder = new NormalViewHolder(v);
break;
}
return viewHolder;
}
For more details you can check this link out.
Upvotes: 1