Create a Custom ListAdapter

The PlayerSummaryAdapter class is responsible for managing all the PlayerSummary items in our list and handling how they’re displayed. We use a custom RecyclerView.ViewHolder inner class (meaning it lives inside PlayerSummaryAdapter) to bind a PlayerSummary item to the layout, then the RecyclerView library handles the rest. All we need to do in PlayerSummaryAdapter is tell the RecyclerView what to do when creating and binding a new ViewHolder plus how to tell the difference between PlayerSummary items in the list.

After creating PlayerSummaryAdapter in the adapters package, first up is the PlayerSummaryViewHolder inner class. The PlayerSummaryAdapter class both contains and depends on this class, so we’ll create it first then wrap PlayerSummaryAdapter around it. The PlayerSummaryViewHolder class inherits from RecyclerView.ViewHolder and has a single function, bind, which takes in a PlayerSummary object.

The bind function doesn’t do much other than assign binding.playerSummary to the item value. The binding value is an instance of PlayerSummaryListItemBinding, which was generated by the Data Binding library when we added the generic <layout> tag to the player_summary_list_item.xml file. The item value, then, is the PlayerSummary object coming into the method. Once that assignment is complete, bind then ensures bindings are executed so the data shows up properly with the executePendingBindings function.

 inner​ ​class​ PlayerSummaryViewHolder(
 private​ ​val​ binding: PlayerSummaryListItemBinding
 ) :
  RecyclerView.ViewHolder(binding.root) {
 
 fun​ ​bind​(item: PlayerSummary) {
  binding.apply {
  playerSummary = item
  executePendingBindings()
  }
  }
 }

The PlayerSummaryAdapter class around this inner class inherits from ListAdapter, which takes two type parameters and a DiffUtil.ItemCallback instance. The type parameters are the type of item in the list (PlayerSummary) and the type of ViewHolder for those items (PlayerSummaryAdapter.PlayerSummaryViewHolder). The callback piece is a new private class at the end of the file called (uncreatively) PlayerSummaryDiffCallback. That class looks like this:

 private​ ​class​ PlayerSummaryDiffCallback :
  DiffUtil.ItemCallback<PlayerSummary>() {
 
 override​ ​fun​ ​areItemsTheSame​(
  oldItem: PlayerSummary,
  newItem: PlayerSummary
  ): Boolean = oldItem.id == newItem.id
 
 override​ ​fun​ ​areContentsTheSame​(
  oldItem: PlayerSummary,
  newItem: PlayerSummary
  ): Boolean = oldItem == newItem
 }

With both PlayerSummaryDiffCallback and PlayerSummaryViewHolder ready, we can get PlayerSummaryAdapter created. This class, which inherits from ListAdapter, will also contain a few overridden functions that we’ll create in a bit. The class declaration plus the other class and function from before together look like this:

 class​ PlayerSummaryAdapter :
  ListAdapter<PlayerSummary, PlayerSummaryAdapter.PlayerSummaryViewHolder>(
  PlayerSummaryDiffCallback()
  ) {
 
 //Overridden functions will go here in a bit.
 
 inner​ ​class​ PlayerSummaryViewHolder(
 private​ ​val​ binding: PlayerSummaryListItemBinding
  ) :
  RecyclerView.ViewHolder(binding.root) {
 
 fun​ ​bind​(item: PlayerSummary) {
  binding.apply {
  playerSummary = item
  executePendingBindings()
  }
  }
  }
 }
 
 private​ ​class​ PlayerSummaryDiffCallback :
  DiffUtil.ItemCallback<PlayerSummary>() {
 
 override​ ​fun​ ​areItemsTheSame​(
  oldItem: PlayerSummary,
  newItem: PlayerSummary
  ): Boolean =
  oldItem.id == newItem.id
 
 override​ ​fun​ ​areContentsTheSame​(
  oldItem: PlayerSummary,
  newItem: PlayerSummary
  ): Boolean =
  oldItem == newItem
 }

An error should be there with the PlayerSummaryAdapter as written since we’ve yet to implement the two abstract functions from ListAdapter: onCreateViewHolder and onBindViewHolder. Both functions are effectively one step, so we can get them done pretty quickly.

onCreateViewHolder needs to know how to build instances of PlayerSummaryViewHolder. That means we’re inflating our layout using the DataBindingUtil class as we have done a few times in this book, sending that into a new PlayerSummaryViewHolder instance, and returning that from the function.

 override​ ​fun​ ​onCreateViewHolder​(
  parent: ViewGroup,
  viewType: Int
 ): PlayerSummaryViewHolder =
  PlayerSummaryViewHolder(
  DataBindingUtil.inflate(
  LayoutInflater.from(parent.context),
  R.layout.player_summary_list_item,
  parent,
 false
  )
  )

onBindViewHolder is even more straightforward, as it uses a PlayerSummaryViewHolder instance from onCreateViewHolder, then sends a PlayerSummary item into the bind function. We use the getItem function from the ListAdapter class to get the correct PlayerSummary based on where we are in the list. This is a major advantage of inheriting from the ListAdapter class—it does almost all the work for us as far as handling the items and retrieving the correct one.

 override​ ​fun​ ​onBindViewHolder​(
  viewHolder: PlayerSummaryViewHolder,
  position: Int
 ) {
  viewHolder.bind(getItem(position))
 }

The PlayerSummaryAdapter is now ready for use, so we can head over to the RankingsFragment class to get everything connected.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.118.99