Sorting Events in Open Event Organizer Android App
While working on Open Event Organizer project, we had to display events in a single list in custom order with proper sub headings. Initially, we were thinking of using tabbed activity and showing events in respective tabs. But the thing with tabs is that it requires you to nest fragments and then each of them will have adapters. Also, we have used Model View Presenter pattern in the project, so this is another reason we did not use view pager as it would increase the number of presenter and view classes for the same feature. So we decided to display events in a single list instead. The custom order decided was that events would be divided into three categories - live, upcoming and past. In each category, a recent event will be at the top of another. Adding SubHeadings support to the Recycler View So the first thing was adding subheading support to the recycler view. We have used timehop's sticky header decorators library for subheadings implementation. First, your adapter should implement the interface StickyRecyclerHeadersAdapter provided by the library. In our case the implemented methods look like: @Override public long getHeaderId(int position) { Event event = events.get(position); return DateService.getEventStatus(event).hashCode(); } @Override public EventsHeaderViewHolder onCreateHeaderViewHolder(ViewGroup viewGroup) { return new EventsHeaderViewHolder(EventSubheaderLayoutBinding.inflate(LayoutInflater.from(viewGroup.getContext()), viewGroup, false)); } @Override public void onBindHeaderViewHolder(EventsHeaderViewHolder holder, int position) { Event event = events.get(position); holder.bindHeader(DateService.getEventStatus(event)); } @Override public int getItemCount() { return events.size(); } The first one is getHeaderId which returns a unique id for a group of items which should appear under a single subheading. In this case, DateService.getEventStatus returns status of an event (either live, past or upcoming) and so hashcode of it is returned as a unique id for that header. OnCreateHeaderViewHolder is same as onCreateViewHolder of your adapter. Return your header view here. Similarly in onBindViewHolder, bind data to the header. getItemCount returns total number of items. Sorting Events The important thing to do was sorting events in the order decided. We had to implement the Comparable interface to Event model which will compare any two events using our custom rules such that after sorting we get events in the order - Live, Upcoming and Past with recent one at the top in each category. The compareTo method of Event model looks like: public int compareTo(@NonNull Event otherEvent) { Date now = new Date(); try { Date startDate = DateUtils.getDate(getStartTime()); Date endDate = DateUtils.getDate(getEndTime()); Date otherStartDate = DateUtils.getDate(otherEvent.getStartTime()); Date otherEndDate = DateUtils.getDate(otherEvent.getEndTime()); if (endDate.before(now) || otherEndDate.before(now)) { // one of them is past and other can be past or live or upcoming return endDate.after(otherEndDate) ? -1 : 1; } else { if (startDate.after(now) || otherStartDate.after(now)) { // one of them is upcoming other can be upcoming or live return startDate.before(otherStartDate) ? -1 : 1; } else { // both are live return startDate.after(otherStartDate) ? -1 : 1; } } } catch (ParseException e) { e.printStackTrace(); } return 1; } The compareTo method returns a positive integer value for greater than, the negative integer value…
