I am currently working on a android project in which there is a Recyclerview
. Recyclerview Holds different types of Items. Items are different files (Doc,Pdf,Images and Videos). I am using Gridlayoutmanager
.I want to inflate two types of views as rows in recyclerview, one view is for the Images and Videos and another view is for other type of files(doc,pdf etc).All the files are mixed, don't know which type of files in which order.I know I have to use getItemViewType
and onCreateViewHolder
to inflate rows. If I use general way which is inflating the row first and filling the row according to the type of row inflated does not work because all the files are random. I want to inflate the row depending on the type of file. May be I need to trigger getItemViewType
from the onBindViewHolder
so as to inflate the type needed. I have read questions in SO. No question is related directly to this problem. All the questions are inflating row first and filling the details in the row. Any Idea how to inflate depending on the type of details(files in my case)?

- 2,637
- 4
- 25
- 44
2 Answers
Create inside You adapter class:
class ViewHolder{
public ViewHolder(View v, int type){
super(itemView);
this.type=type; //here we have type of view holder
}
}
In Adapter implement method:
final int VIEW_VIDEO=2;
final int VIEW_STANDARD=1;
public int getItemViewType(int position) {
//here return some view type
if (isVideo(position)){ //example method checking is video row
return VIEW_VIDEO;
}else{
return VIEW_STANDARD
}
}
If I use general way which is inflating the row first and filling the row according to the type of row inflated does not work because all the files are random
In getItemViewType You have position so maybe this is when it can be checked what kind of file in this row is. If your adapter has data ( if list displays then for sure has ) then it can be checked what kind of file we will need to set on view.
Example isVideo method checking file extension:
private boolean isVideo(position){
String filename=list.get(position); //list Your Strings
String filenameArray[] = filename.split("\\.");
String extension = filenameArray[filenameArray.length-1];
return extension=="mp4"; //change this to more flexible
}
Next method to implement in Adapter:
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View v;
if (viewType==VIEW_VIDEO){
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.video_layout, parent, false);
}else{
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.standard_layout, parent, false);
}
return new ViewHolder(v,viewType); //here we have view holder with right view
}
Last thing in Adapter:
public void onBindViewHolder(final ViewHolder holder, int position){
if (holder.type==VIEW_VIDEO){
//staff on video
}
}

- 19,374
- 4
- 49
- 50
-
Thanks for the reply. In `getItemViewtype` I cannot check whether the row is a Video file or Normal file just using the "position" parameter. files are mixed. I cannot say type of file by using its position. That is what my problem. – Naroju Jul 30 '16 at 16:11
-
So when You know what it is? What data in adapter You have? – Maciej Sikora Jul 30 '16 at 16:12
-
I input a ArrayList of file names(Strings) into the Adapter class constructor. So the ArrayList Contains file names randomly,I don't know which type of file consists for particuler position. Is there a way that I could inflate depending on the file extension? – Naroju Jul 30 '16 at 16:17
-
If You have extensions in Strings then my example isVideo method shoud check string for extension and returns true if is movie extension – Maciej Sikora Jul 30 '16 at 16:19
-
http://stackoverflow.com/questions/4894885/how-to-check-file-extension-in-android here You have how check extension – Maciej Sikora Jul 30 '16 at 16:21
-
I added some example of isVideo in answer – Maciej Sikora Jul 30 '16 at 16:23
-
Thank you it helps – Naroju Jul 30 '16 at 16:24
There are really numerous solutions but this one is my favorite:
public class FeedAdapter extends RecyclerView.Adapter<FeedAdapter.FeedItemHolder> {
static final int VIEW_TYPE_HEADER = 0;
static final int VIEW_TYPE_NORMAL = 1;
static final int VIEW_TYPE_FOOTER = 2;
@Override
public FeedItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
logd("create view holder called");
int resid = 0;
if (viewType == VIEW_TYPE_HEADER) {
resid = R.layout.item_header;
} else if (viewType == VIEW_TYPE_NORMAL) {
resid = R.layout.item_normal;
} else if (viewType == VIEW_TYPE_FOOTER) {
resid = R.layout.item_footer;
}
View v = LayoutInflater.from(context).inflate(resid, parent, false);
return new FeedItemHolder(context, viewType);
}
private void bindNormal(FeedItemHolder holder, int position) {
// specialized bind method for normal items
...
}
private void bindHeader(FeedItemHolder holder, int position) {
// specialized bind method for header items
...
}
private void bindFooter(FeedItemHolder holder, int position) {
// specialized bind method for footer items
...
}
@Override
public void onBindViewHolder(FeedItemHolder holder, int position) {
int viewType = getItemViewType(position);
if (viewType == VIEW_TYPE_HEADER) {
bindHeader(holder, position);
} else if (viewType == VIEW_TYPE_NORMAL) {
bindNormal(holder, position);
} else if (viewType == VIEW_TYPE_FOOTER) {
bindFooter(holder, position);
}
}
@Override
public int getItemViewType(int position) {
// determine view type, e.g:
//
// if (position == 0)
// return VIEW_TYPE_HEADER;
// else if (postion > itemCount)
// return VIEW_TYPE_FOOTER;
// else
// return VIEW_TYPE_NORMAL;
...
}
private View.OnClickListener showCommentsListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (holder != null) {
TimelineEntryRaw entry = (TimelineEntryRaw) v.getTag();
holder.onCommentsRequest(entry, false);
}
}
};
public class FeedItemHolder extends RecyclerView.ViewHolder {
private View root;
// header items' views
private TextView title;
...
// normal items' views
private TextView contentText;
...
// footer items' views
private View loadMoreBtn;
...
public FeedItemHolder(View itemView, int itemType) {
// the call to parent constructor is the only
// reason android knows which view to show
super(itemView);
root = itemView;
if (itemType == VIEW_TYPE_HEADER) {
// fetch header item views
loadMoreBtn = findView(itemView, R.id.item_header__title);
...
}
if (itemType == VIEW_TYPE_NORMAL) {
// fetch views for normal item
contentText = findView(itemView, R.id.item_normal__content);
...
}
if (itemType != VIEW_TYPE_FOOTER) {
// fetch views for footer item
loadMoreBtn = findView(itemView, R.id.item_footer__btn);
...
}
} // end Holder constructor
} // end class Holder
}
long story short, in create-view-holder and bind-view-holder you got to create and bind the view based on its view type

- 2,167
- 26
- 31