Search code examples
androidlistviewbaseadapterandroid-recyclerview

How to inflate different layout in RecyclerView based on its position in onCreateViewHolder method


I am trying to refactor my ListView to RecyclerView and I stuck in this situation.

In my ListView Adapter i have something like this:

@Override
public int getItemViewType(int position) {
    if (mDecommissionMode && position == getCount() - 1)
        return 1;
    return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    if (getItemViewType(position) == 0)
        return getNormalView(position, convertView, parent);
    else
        return getManualDecommissionView(convertView, parent);

}

I don't have an idea how can I apply this to my RecyclerView adapter because I don't have access to the position in onCreateViewHolder method, where the layout should be inflated.

Here are the methods in my RecyclerView Adapter:

@Override
public DevicesItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    DevicesRecyclerViewAdapter.DevicesItemViewHolder holder = new DevicesItemViewHolder(); //should pass some inflated view to ViewHolder instance
    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mOnClickListener.onClick(view);
        }
    });
    return holder;
}


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


}

Is there a way I can cope with it?


Solution

  • Create Two View Holders for two Layouts

    Follow these three simple steps

    • Override getItemViewType(int position)

    • Return different ViewHolders based on the ViewType in onCreateViewHolder() method

    • Populate View based on the itemViewType in onBindViewHolder() method (This solves the position problem you are facing)

    Here is a small code snippet for RecyclerView Adapter
    You can see the full code for reference Here

    public class YourListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    
    private static final int LAYOUT_ONE= 0;
    private static final int LAYOUT_TWO= 1;
    
    @Override
    public int getItemViewType(int position)
    {
        if(position==0)
            return LAYOUT_ONE;
        else
            return LAYOUT_TWO;
    }
    
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
    
        View view =null;
        RecyclerView.ViewHolder viewHolder = null;
    
        if(viewType==LAYOUT_ONE)
        {
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.one,parent,false);
            viewHolder = new ViewHolderOne(view);
        }
        else
        {
            view = LayoutInflater.from(parent.getContext()).inflate(R.layout.two,parent,false);
            viewHolder= new ViewHolderTwo(view);
        }
    
        return viewHolder;
    }
    
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
    
    
        if(holder.getItemViewType()== LAYOUT_ONE)
        {
    
        }
        else {
    
            ViewHolderOne vaultItemHolder = (ViewHolderOne) holder;
            vaultItemHolder.name.setText(displayText);
            vaultItemHolder.name.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    .......
                }
            });
    
        }
    
         
    }
    
    
    
    public class ViewHolderOne extends RecyclerView.ViewHolder {
    
        public TextView name;
        
        public ViewHolderOne(View itemView) {
            super(itemView);
            name = (TextView)itemView.findViewById(R.id.displayName);
            
        }
    }
    
    public class ViewHolderTwo extends RecyclerView.ViewHolder{
    
        public ViewHolderTwo(View itemView) {
            super(itemView);
            
            ..... Do something
        }
    }
    }