0

So this is my FeedAdapter:

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

    private final int VIEW_TYPE_VERTICAL = 1;
    private final int VIEW_TYPE_HORIZONTAL = 2;
    private final int VIEW_TYPE_AD = 3;
    private Context context;
    private ArrayList<Object> items;
    private List<Vertical> listVertical;
    private List<Horizontal> listHorizontal;
    private List<Adlist> listAd;

    public FeedAdapter(Context context, ArrayList<Object> items, List<Vertical> listVertical,List<Horizontal> listHorizontal, List <Adlist> adList) {
    this.context = context;
    this.items = items;
    this.listVertical = listVertical;
    this.listHorizontal = listHorizontal;
    this.listAd = adList;
    }

I have a horizontal, vertical and a alternative AD view (this has nothing to do with Goggle Ad Service btw) in my Feed. Items = three different items, so three different views

Fot a better understanding: this the onCreate Method:

public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view;
RecyclerView.ViewHolder holder = null;

switch (viewType) {
    case VIEW_TYPE_VERTICAL:
        view = inflater.inflate(R.layout.newsfeed_vertical,viewGroup,false);
        holder = new VerticalViewHolder(view);
        break;
    case VIEW_TYPE_HORIZONTAL:
        view = inflater.inflate(R.layout.newsfeed_horizontal,viewGroup,false);
        holder = new HorizontalViewHolder(view);
        break;
    case VIEW_TYPE_AD:
        view = inflater.inflate(R.layout.newsfeed_vertical,viewGroup,false);
        holder = new AdViewHolder(view);
        break;

an this the onBindViewHolder:

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    if (holder.getItemViewType() == VIEW_TYPE_VERTICAL)
        verticalView((VerticalViewHolder) holder);

    else if (holder.getItemViewType() == VIEW_TYPE_HORIZONTAL)
        horizontalView((HorizontalViewHolder) holder);

    else if (holder.getItemViewType() == VIEW_TYPE_AD)
        adView((AdViewHolder) holder);
}
    public void verticalView (VerticalViewHolder holder ){

    VerticalScrollAdapter adapter_v = new VerticalScrollAdapter(listVertical);
    holder.recyclerView.setLayoutManager(new LinearLayoutManager(context));
    holder.recyclerView.setAdapter(adapter_v);

}

public void horizontalView (HorizontalViewHolder holder) {
    HorizontalScrollAdapter adapter_h = new HorizontalScrollAdapter(listHorizontal);
    holder.recyclerView.setLayoutManager(new LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL,false));
    holder.recyclerView.setAdapter(adapter_h);
}

public void adView (AdViewHolder holder) {
    AdScrollAdapter adapter_ad = new AdScrollAdapter(adList);
    holder.recyclerView.setLayoutManager(new LinearLayoutManager(context));
    holder.recyclerView.setAdapter(adapter_ad);

}

So I'm using the getItemViewType to understand which view I'm parsing:

@Override
public int getItemCount() {
    Log.e("items.size", String.valueOf(items.size()));
    return items.size();
}


@Override
public int getItemViewType(int position) {

    if (items.get(position) instanceof Vertical)
        return VIEW_TYPE_VERTICAL;

    if (items.get(position) instanceof Horizontal)
        return VIEW_TYPE_HORIZONTAL;

    if(items.get(position) instanceof Adlist)
        return VIEW_TYPE_AD;
    return -1;
}

But with this my Feed get's the following structure:

  • VERTICAL VIEW
  • HORIZONTAL VIEW
  • AD VIEW

I'd like to organize my Feed like this

VERTIAL VIEW [0] = only 1 view (a box basically) with the first position of the LinearLayout Manager
HORIZONTAL VIEW = full list of my horizontal Views here / second position of my LinearLayoutManager
AD VIEW [0] = at the third position
VERTICAL VIEW [1-5]
AD VIEW [1] = @ position 6 in the LinearLayout
VERTICAL VIEW [5- ** ] 

So I know I have to work with findViewHolderForAdapterPosition and findViewHolderForLayoutPosition, but: Where do I have put these in my Code?

KayD
  • 372
  • 5
  • 17

1 Answers1

0

Sort/construct your items list so that it has the items in the correct order.

Ideally, you'd start with your three types partitioned (i.e. one list of Vertical items, a second list of Horizontal items, and a third list of Ad items). Then you could build your overall list like this:

this.items = new ArrayList<>();

if (listVertical.size() > 0) {
    items.add(listVertical.remove(0));
}

if (listHorizontal.size() > 0) {
    items.add(listHorizontal.remove(0));
}

while (listVertical.size() > 0 || listAd.size() > 0) {    
    if (listAd.size() > 0) {
        items.add(listAd.remove(0));
    }

    int count = 5;

    while (count > 0 && listVertical.size() > 0) {
        items.add(listVertical.remove(0));
    }
}

This will add one vertical view, then one horizontal view, and then one ad view + five vertical views in a loop until you "run out" of both ad views and vertical views. I believe that matches your desired structure.

At the end, your three lists will be empty (because you will have remove()d all items from them). If you need to avoid this, you can create copies:

List<Vertical> verticalCopy = new ArrayList<>(listVertical);
// and so on

And then you can just use verticalCopy instead of listVertical in the above code.

Ben P.
  • 52,661
  • 6
  • 95
  • 123
  • Hey! Thank you for your time, I now have my items in the correct order but have a look at my onBindViewHolder Update: the ViewHolders are connected to my ListVertical, listHorizontal and adLists and because auf that everything gets displayed twice in my List. So now I should connect the ViewHolders to my "items" or would this be the wrong way? – KayD May 27 '19 at 20:18
  • 1
    Yes. Whatever list you're using to "back" your adapter should be what you use in your `onBindViewHolder()` method. In this case, we're sorting/arranging all the items in your `items` list, we're returning `items.size()` from `getItemCount()`, and using `items.get(position)` in `getItemViewType()`. As such, you should also use `items.get(position)` in `onBindViewHolder()`. – Ben P. May 27 '19 at 20:43
  • Well basically you're a god of teaching, thank you! My problem was to get this expression here - casting the items to the correct ArrayList to load them with the Adapter: 'ArrayList value = new ArrayList<>(Arrays.asList((Adlist) items.get(position)));' (just asking: could this be shorter? it looks way to complicated for me) – KayD May 28 '19 at 20:04