CCJ
CCJ

Reputation: 1751

How to insert list item into listview without modifying the underlying data set?

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

Answers (1)

Soufiane ROCHDI
Soufiane ROCHDI

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:

  1. 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;
    }
    
  2. 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

Related Questions