Creating multiple Attendee Details sections in Open Event Android

Whenever a User picks the quantities of tickets he/she wants to buy for an event, that no of ticket details are required to be provided by the user. For this multiple attendee details section is displayed so that user can type in the information of all the Attendee. This blog post will help you understand how this is implemented in Open Event Android

The idea is to create a Recycler View for attendee objects and add empty attendee objects to the recycler based on what total quantity of tickets are selected by the User. For this first, we will have to create a Recycler View for attendee objects.

RecyclerView for Attendee Objects

Just like any other recycler view, we have to follow the following steps to build the Recycler View

  • Create the layout for single Attendee item.
  • Create a RecyclerAdapter recycler view
  • Create ViewHolder for recycler view

The layout for single attendee item contains editable fields such as First name, Last name, Email, Country and a view which can hold custom forms (if required for that Event Ticket). The Recycler Adapter for attendee has an ArrayList of Attendee which is what is rendered on the fragment, it also has a list of tickets such that attendee at a certain position in ArrayList is for the ticket at the corresponding position in ticket list. We also have some regular recycler adapter functions to insert values into these class variables. We pass a link of the recycler adapter object to the view holder so that these variables can be accessed from the view holder too.

override fun onBindViewHolder(holder: AttendeeViewHolder, position: Int) {
       holder.bind(this, position)
   }

We send the position to the view holder as to know which attendee and ticket from the list of attendees and tickets should the view be created for.

The view holder is responsible for creating views for a single recycler view item and how it should behave when any action is performed on that view.

Since we are dealing with editable text view for getting attendee details from the user, we have set up a Text watcher to listen for text change in any of these view objects. Whenever text is changed in any of these views the corresponding attendee in attendee recycler is automatically updated.  The following is the implementation of text watcher.

 textWatcher = object : TextWatcher {
           override fun afterTextChanged(p0: Editable?) {
               val id = attendeeRecyclerAdapter.attendeeList[position].id
               attendeeRecyclerAdapter.attendeeList.removeAt(position)
               val attendee = Attendee(id, firstname = itemView.attendeeItemFirstName.text.toString(),
                       lastname = itemView.attendeeItemLastName.text.toString(),
                       email = itemView.attendeeItemEmail.text.toString(),
                       city = getAttendeeField(“city”),
                       address = getAttendeeField(“address”),
                       state = getAttendeeField(“state”),
                       country = itemView.attendeeItemCountry.text.toString(),
                       ticket = TicketId(attendeeRecyclerAdapter.ticketList[position].id.toLong()),
                       event = attendeeRecyclerAdapter.eventId)
               attendeeRecyclerAdapter.attendeeList.add(position, attendee)
           }

             }

Now that our recycler adapter is ready we just have to wire the adapter with the recycler view in the Attendee Fragment.

<android.support.v7.widget.RecyclerView
               android:id=“@+id/attendeeRecycler”
               android:layout_width=“match_parent”
               android:layout_height=“wrap_content” />

Adding the above in attendee fragment will create a recycler view. Next step is too wire everything and insert attendee and ticket according to the user.

Inserting Attendees and Tickets in the Recycler

We have set up an observer on the tickets variable of Attendee View model which means that any update in the tickets will automatically call it with latest values. We are inserting all the tickets into the ticket list of the recycler adapter and also for every ticket we are generating a no of attendees according to the value of ticket’s quantity.

attendeeFragmentViewModel.tickets.observe(this, Observer {
               it?.let {
                   ticketsRecyclerAdapter.addAll(it)
                   ticketsRecyclerAdapter.notifyDataSetChanged()
                   it.forEach {
                    val pos = ticketIdAndQty?.map { it.first }?.indexOf(it.id)
                   val iterations = pos?.let { it1 ->       ticketIdAndQty?.get(it1)?.second } ?: 0
                  for (i in 0 until iterations)
                               attendeeRecyclerAdapter.add(Attendee(attendeeFragmentViewModel.getId()), it)
                  attendeeRecyclerAdapter.notifyDataSetChanged()
                     }
    }

In the code snippet shown above, pos = ticketIdAndQty?.map { it.first }?.indexOf(it.id) helps in getting the position of ticket id and its quantity pair from the list of pairs whenever we find a ticket. Using the position value we take can get the second variable in a pair which is the quantity of that ticket. Now that we know ticket details and the quantity of same to be inserted into the recycler we can create empty attendee objects and add them to the adapter with there ticket id as current ticket id and this goes till the quantity limit for the current ticket is reached. These attendees can now be edited by the user and when the user is done providing details the order will take the details of different attendees and create the order.

References