Sobes.tech
Middle

Hoe los je het probleem met verschillende weergavertypes voor RecyclerView op?

sobes.tech AI

Antwoord van AI

Er zijn verschillende benaderingen:

  1. Gebruik van meerdere ViewTypes in de adapter. Dit is de meest voorkomende en flexibele methode. De adapter overschrijft de methode getItemViewType, die het type weergave voor een specifieke positie retourneert. Vervolgens wordt dit type gebruikt in de methoden onCreateViewHolder en onBindViewHolder om de juiste ViewHolder te maken en te binden.

    class MyAdapter(private val items: List<Item>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    
        private val VIEW_TYPE_TEXT = 0
        private val VIEW_TYPE_IMAGE = 1
    
        override fun getItemViewType(position: Int): Int {
            return when (items[position]) {
                is TextItem -> VIEW_TYPE_TEXT
                is ImageItem -> VIEW_TYPE_IMAGE
            }
        }
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
            return when (viewType) {
                VIEW_TYPE_TEXT -> {
                    val view = LayoutInflater.from(parent.context).inflate(R.layout.item_text, parent, false)
                    TextViewHolder(view)
                }
                VIEW_TYPE_IMAGE -> {
                    val view = LayoutInflater.from(parent.context).inflate(R.layout.item_image, parent, false)
                    ImageViewHolder(view)
                }
                else -> throw IllegalArgumentException("Ongeldig weergavetype")
            }
        }
    
        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
            when (holder.itemViewType) {
                VIEW_TYPE_TEXT -> {
                    val textHolder = holder as TextViewHolder
                    val textItem = items[position] as TextItem
                    textHolder.bind(textItem)
                }
                VIEW_TYPE_IMAGE -> {
                    val imageHolder = holder as ImageViewHolder
                    val imageItem = items[position] as ImageItem
                    imageHolder.bind(imageItem)
                }
            }
        }
    
        override fun getItemCount(): Int {
            return items.size
        }
    
        // ViewHolders voor verschillende types
        class TextViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            private val textView: TextView = itemView.findViewById(R.id.textView)
            fun bind(item: TextItem) {
                textView.text = item.text
            }
        }
    
        class ImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
            private val imageView: ImageView = itemView.findViewById(R.id.imageView)
            fun bind(item: ImageItem) {
                // Afbeelding laden
            }
        }
    }
    
    data class TextItem(val text: String)
    data class ImageItem(val imageUrl: String)
    
  2. Gebruik van bibliotheken. Er zijn bibliotheken die het werken met meerdere ViewTypes vereenvoudigen, zoals Groupie of Epoxy. Ze bieden abstracties voor het definiëren van "items" met bijbehorende ViewHolders en bindinglogica.

    • Groupie:

      class MyItemAdapter(private val items: List<GroupieItem<*>>) : GroupAdapter<ViewHolder>() {
          init {
              addAll(items)
          }
      }
      
      // Voorbeeld van een Groupie Item
      class TextItemGroupie(private val text: String) : Item<ViewHolder>() {
          override fun getLayout(): Int = R.layout.item_text
      
          override fun bind(viewHolder: ViewHolder, position: Int) {
              viewHolder.itemView.findViewById<TextView>(R.id.textView).text = text
          }
      }
      
      class ImageItemGroupie(private val imageUrl: String) : Item<ViewHolder>() {
          override fun getLayout(): Int = R.layout.item_image
      
          override fun bind(viewHolder: ViewHolder, position: Int) {
             // Afbeelding laden
          }
      }
      
    • Epoxy: Gebruikt annotaties voor het genereren van EpoxyModel en EpoxyController.

  3. Gebruik van samengestelde ViewHolders. Een minder gebruikelijke aanpak waarbij één ViewHolder meerdere verschillende weergaven bevat en de zichtbare weergave wordt gekozen binnen de ViewHolder (via setVisibility of andere methoden). Niet aanbevolen voor veel verschillende types of complexe logica.

  4. Splitsen van gegevens. Als de gegevens duidelijk kunnen worden opgesplitst in groepen met verschillende weergaven, kunnen meerdere onafhankelijke RecyclerViews worden gebruikt (wat vaak niet optimaal is) of een samenstelling van adapters.