Sobes.tech
Middle

Ինչպես լուծել RecyclerView-ի տարբեր տեսակի ներկայացումների խնդիրը?

sobes.tech AI

Պատասխան AI-ից

Կան մի քանի մոտեցումներ:

  1. Բազմափող ViewTypes օգտագործում ադապտերում։ Ամենատարածված և ճկուն միջոցը։ Ադապտերը վերագրում է getItemViewType մեթոդը, որը վերադարձնում է կոնկրետ դիրքի տեսակի տեսակը։ Այնուհետև այս տեսակը օգտագործվում է onCreateViewHolder և onBindViewHolder մեթոդներում համապատասխան ViewHolder ստեղծելու և կապելու համար։

    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("Անվավեր տեսակի տեսք")
            }
        }
    
        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
        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) {
                // Լուսանկարի բեռնում
            }
        }
    }
    
    data class TextItem(val text: String)
    data class ImageItem(val imageUrl: String)
    
  2. Բոլորածր գրադարանների օգտագործում։ Կան գրադարաններ, որոնք հեշտացնում են մի քանի ViewTypes-ի աշխատանքը, օրինակ՝ Groupie կամ Epoxy։ Նրանք տրամադրում են աբստրակցիաներ items-ների համար համապատասխան ViewHolders և կապի լոգիկայի համար։

    • Groupie:

      class MyItemAdapter(private val items: List<GroupieItem<*>>) : GroupAdapter<ViewHolder>() {
          init {
              addAll(items)
          }
      }
      
      // 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) {
             // Լուսանկարի բեռնում
          }
      }
      
    • Epoxy: Օգտագործում է նշաններ EpoxyModel և EpoxyController գեներացնելու համար։

  3. Կոմպոզիցիոն ViewHolders օգտագործում։ Ավելի քիչ տարածված մոտեցում, երբ մեկ ViewHolder պարունակում է մի քանի տարբեր տեսակի դրսևորումներ, և տեսանելի դրսևորումը որոշվում է ViewHolder-ի ներսում (մասամբ setVisibility կամ այլ մեթոդներով): Չի խորհուրդ տրվում մեծ թվով տարբեր տեսակի կամ բարդ լոգիկայի համար։

  4. Տվյալների բաժանում։ Եթե տվյալները կարելի է հստակ բաժանել տարբեր խմբերի, որոնք ունեն տարբեր դրսևորումներ, կարելի է օգտագործել մի քանի անկախ RecyclerViews (որը հաճախ անարդյունավետ է) կամ կոմպոզիցիա ադապտերների։