Divide elements on groups in RecyclerView or Grouping Recyclerview items ,say by date
i want to group my android RecyclerView
items with a header made based on date like this:
1 week ago
- item
- item
- item
- item
2 weeks ago
- item
- item
- item
that sort of thing or grouping based on some element.
Here is a solution i came by with the aid of alot research over the net and this blog link as well Kartikey Kuswhaha so its not all my credit but i just want to give more clarity to it. below is the code: create the following files:PojoOfJsonArray,MainActivity, ListItem ,GeneralItem ,DateItem , Adapter
PojoOfJsonArray.java -this file wil represent your POJO class or whatever pojo you got going on in your app so:
public class PojoOfJsonArray {
public PojoOfJsonArray(String name, String date) {
this.name = name;
this.date = date;
}
private String name,date;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
MainActivity.java this is the activity that you will use to implement you recyclerview :
public class MainActivity extends AppCompatActivity {
private List<PojoOfJsonArray> myOptions = new ArrayList<>();
List<ListItem> consolidatedList = new ArrayList<>();
private RecyclerView mRecyclerView;
private Adapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
mRecyclerView.setHasFixedSize(true);
myOptions.add(new PojoOfJsonArray("name 1", "2016-06-21"));
myOptions.add(new PojoOfJsonArray("name 2", "2016-06-05"));
myOptions.add(new PojoOfJsonArray("name 2", "2016-06-05"));
myOptions.add(new PojoOfJsonArray("name 3", "2016-05-17"));
myOptions.add(new PojoOfJsonArray("name 3", "2016-05-17"));
myOptions.add(new PojoOfJsonArray("name 3", "2016-05-17"));
myOptions.add(new PojoOfJsonArray("name 3", "2016-05-17"));
myOptions.add(new PojoOfJsonArray("name 2", "2016-06-05"));
myOptions.add(new PojoOfJsonArray("name 3", "2016-05-17"));
HashMap<String, List<PojoOfJsonArray>> groupedHashMap = groupDataIntoHashMap(myOptions);
for (String date : groupedHashMap.keySet()) {
DateItem dateItem = new DateItem();
dateItem.setDate(date);
consolidatedList.add(dateItem);
for (PojoOfJsonArray pojoOfJsonArray : groupedHashMap.get(date)) {
GeneralItem generalItem = new GeneralItem();
generalItem.setPojoOfJsonArray(pojoOfJsonArray);//setBookingDataTabs(bookingDataTabs);
consolidatedList.add(generalItem);
}
}
adapter = new Adapter(this, consolidatedList);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(adapter);
}
private HashMap<String, List<PojoOfJsonArray>> groupDataIntoHashMap(List<PojoOfJsonArray> listOfPojosOfJsonArray) {
HashMap<String, List<PojoOfJsonArray>> groupedHashMap = new HashMap<>();
for (PojoOfJsonArray pojoOfJsonArray : listOfPojosOfJsonArray) {
String hashMapKey = pojoOfJsonArray.getDate();
if (groupedHashMap.containsKey(hashMapKey)) {
// The key is already in the HashMap; add the pojo object
// against the existing key.
groupedHashMap.get(hashMapKey).add(pojoOfJsonArray);
} else {
// The key is not there in the HashMap; create a new key-value pair
List<PojoOfJsonArray> list = new ArrayList<>();
list.add(pojoOfJsonArray);
groupedHashMap.put(hashMapKey, list);
}
}
return groupedHashMap;
}
}
the myOptions is where one would use to feed your data into. ListItem.java
public abstract class ListItem {
public static final int TYPE_DATE = 0;
public static final int TYPE_GENERAL = 1;
abstract public int getType();
}
GeneralItem.java
public class GeneralItem extends ListItem {
private PojoOfJsonArray pojoOfJsonArray;
public PojoOfJsonArray getPojoOfJsonArray() {
return pojoOfJsonArray;
}
public void setPojoOfJsonArray(PojoOfJsonArray pojoOfJsonArray) {
this.pojoOfJsonArray = pojoOfJsonArray;
}
@Override
public int getType() {
return TYPE_GENERAL;
}
}
DateItem.java
public class DateItem extends ListItem {
private String date;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
@Override
public int getType() {
return TYPE_DATE;
}
}
Adapter.java this adapter is for the recyclerview if your not well informed on how to make simple sectioned recyclerview then i suggest you read on those and be good in the area because this is abit more tricky anyways:
public class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
List<ListItem> consolidatedList = new ArrayList<>();
public Adapter(Context context, List<ListItem> consolidatedList) {
this.consolidatedList = consolidatedList;
this.mContext = context;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case ListItem.TYPE_GENERAL:
View v1 = inflater.inflate(R.layout.items, parent,
false);
viewHolder = new GeneralViewHolder(v1);
break;
case ListItem.TYPE_DATE:
View v2 = inflater.inflate(R.layout.itemsh, parent, false);
viewHolder = new DateViewHolder(v2);
break;
}
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
switch (viewHolder.getItemViewType()) {
case ListItem.TYPE_GENERAL:
GeneralItem generalItem = (GeneralItem) consolidatedList.get(position);
GeneralViewHolder generalViewHolder= (GeneralViewHolder) viewHolder;
generalViewHolder.txtTitle.setText(generalItem.getPojoOfJsonArray().getName());
break;
case ListItem.TYPE_DATE:
DateItem dateItem = (DateItem) consolidatedList.get(position);
DateViewHolder dateViewHolder = (DateViewHolder) viewHolder;
dateViewHolder.txtTitle.setText(dateItem.getDate());
// Populate date item data here
break;
}
}
// ViewHolder for date row item
class DateViewHolder extends RecyclerView.ViewHolder {
protected TextView txtTitle;
public DateViewHolder(View v) {
super(v);
this.txtTitle = (TextView) v.findViewById(R.id.txt);
}
}
// View holder for general row item
class GeneralViewHolder extends RecyclerView.ViewHolder {
protected TextView txtTitle;
public GeneralViewHolder(View v) {
super(v);
this.txtTitle = (TextView) v.findViewById(R.id.txt);
}
}
@Override
public int getItemViewType(int position) {
return consolidatedList.get(position).getType();
}
@Override
public int getItemCount() {
return consolidatedList != null ? consolidatedList.size() : 0;
}
}
and this has two layout being used . thus all
You can use the library SectionedRecyclerViewAdapter to easily group your data into sections and add a header to each section.
First create a Section class:
class MySection extends StatelessSection {
String title;
List<String> list;
public MySection(String title, List<String> list) {
// call constructor with layout resources for this Section header, footer and items
super(R.layout.section_header, R.layout.section_item);
this.title = title;
this.list = list;
}
@Override
public int getContentItemsTotal() {
return list.size(); // number of items of this section
}
@Override
public RecyclerView.ViewHolder getItemViewHolder(View view) {
// return a custom instance of ViewHolder for the items of this section
return new MyItemViewHolder(view);
}
@Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position) {
MyItemViewHolder itemHolder = (MyItemViewHolder) holder;
// bind your view here
itemHolder.tvItem.setText(list.get(position));
}
@Override
public RecyclerView.ViewHolder getFooterViewHolder(View view) {
return new MyFooterViewHolder(view);
}
@Override
public void onBindFooterViewHolder(RecyclerView.ViewHolder holder) {
MyFooterViewHolder footerHolder = (MyFooterViewHolder) holder;
// bind your footer view here
footerHolder.tvItem.setText(title);
}
}
Then you set up the RecyclerView with your Sections:
// Create an instance of SectionedRecyclerViewAdapter
SectionedRecyclerViewAdapter sectionAdapter = new SectionedRecyclerViewAdapter();
// Create your sections with the list of data for each year
MySection section1 = new MySection("1 week ago", week1data);
MySection section2 = new MySection("2 weeks ago", week2data);
// Add your Sections to the adapter
sectionAdapter.addSection(section1);
sectionAdapter.addSection(section2);
// Set up your RecyclerView with the SectionedRecyclerViewAdapter
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(sectionAdapter);