Reputation: 35060
In iOS UITableView
could have 'sections' and inside a section 'rows'. Is this possible in Android with RecycleView
?
RecyclerView.Adapter
has only a getItemCount()
delegate method. But nothing for sections. What alternatives you can suggest?
I thought to put the section headers into a row, and melt the sections into one global section, and so no section will need. Any better idea?
Upvotes: 0
Views: 1441
Reputation: 1415
RecyclerView.Adapter supports multiple view types out of the box. It's up to you which item type you want to display at any particular position. You can easily use it to create sections, for example if you define two item types TYPE_HEADER and TYPE_ITEM:
@Override
public int getItemViewType(int position) {
if (isHeader(position)) {
return TYPE_HEADER;
} else {
return TYPE_ITEM;
}
}
Then, you can use onCreateViewHolder
to inflate proper layouts and onBindViewHolder
to make use of it.
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEADER) {
View v = ... ; // inflate here
return new HeaderViewHolder(v);
} else {
View v = ... ; // inflate here
return new ItemViewHolder(v);
}
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
if (holder instanceof HeaderViewHolder) {
// handle header
} else if (holder instanceof ItemViewHolder {
// handle item
}
}
The only thing left is data structure to keep stuff. There are many ways to implement it and I think it's a little bit out of the scope of your question. If data structure is very deep I prefer using custom tree-like structure I made some time ago but sometimes I use flat List
and check item types using instanceof
.
Upvotes: 1
Reputation: 3711
Override getItemViewType()
method to return Type of your section. And in onCreateViewHolder()
method inflate your layout according to type.
finally in onBindViewHolder()
method render your views according to the type again
following is dummy RecyclerViewAdapter that may help you
class CustomRecyclerViewAdapter extends RecyclerView.Adapter<CustomRecyclerViewAdapter.ViewHolder> {
public final int NEWS_LAYOUT = 0;
public final int ARTICLE_LAYOUT = 1;
public final int PROGRESS_BAR_LAYOUT = 2;
ArrayList<YourModel> list;
Context context;
public CustomRecyclerViewAdapter(Context context) {
this.context = context;
}
@Override
public CustomRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
ViewHolder vh = null;
View v;
switch (viewType) {
case NEWS_LAYOUT:
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_card_view, parent, false);
vh = new ViewHolder(v, viewType);
break;
case ARTICLE_LAYOUT:
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.layout_card_view, parent, false);
vh = new ViewHolder(v, viewType);
break;
case PROGRESS_BAR_LAYOUT:
v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.progress_bar, parent, false);
vh = new ViewHolder(v, viewType);
break;
default:
break;
}
return vh;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
try {
//assign data according to your types
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public int getItemCount() {
return list.size();
}
public void addAll(List list) {
if (null == this.list)
this.list = new ArrayList<>(;
else {
this.list.addAll(list);
}
}
public void clear() {
list.clear();
}
@Override
public int getItemViewType(int position) {
if (list.get(postion).getType().equals("News Layout")) {
return NEWS_LAYOUT;
} else if (list.get(postion).getType().equals("Article Layout")) {
return ARTICLE_LAYOUT;
} else if (list.get(postion).getType().equals("progressbar"))
return PROGRESS_BAR_LAYOUT;
}
return -1;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public CardView cardView;
public ProgressBar progressBar;
public ViewHolder(View view, int type) {
super(view);
if (type == NEWS_LAYOUT || type == ARTICLE_LAYOUT) {
this.cardView = (CardView) view.findViewById(R.id.card_view);
this.cardView.setOnClickListener(this);
} else if (type == PROGRESS_BAR_LAYOUT) {
this.progressBar = (ProgressBar) view.findViewById(R.id.recycler_view_progress_bar);
}
}
@Override
public void onClick(View view) {
//perform operations
}
}
}
Upvotes: 0