MultiType

repository·master·Indexed 26 days ago

https://github.com/drakeet/multitype

An Android library designed to simplify the creation of RecyclerViews with multiple item types. It allows developers to manage different data classes by registering specific delegates, removing the need to manually override getItemViewType. The library supports AndroidX (v4.3.0) and Android Support Library (v3.4.4), providing ItemViewDelegate for XML layouts and ViewDelegate for custom Views.

Tokens
1.6K
Snippets
5
Records
7
Agent score
41%

What's inside MultiType

  1. Overview of MultiType library

    master
    MultiType is an Android library designed to simplify the creation of list views (such as RecyclerView) that contain multiple different item types. It provides a flexible way to manage various view holders and layouts within a single list.
  2. Install MultiType via Gradle

    master

    To use MultiType in your Android project, add the dependency to your build.gradle file.

    Note on Versions:

    • AndroidX (Current): Use com.drakeet.multitype:multitype:4.3.0.
    • Android Support Library: Use me.drakeet.multitype:multitype:3.4.4 and me.drakeet.multitype:multitype-kotlin:3.4.4.
    • Non-Kotlin projects: Use me.drakeet.multitype:multitype:3.5.0.
    dependencies {
      implementation 'com.drakeet.multitype:multitype:4.3.0'
    }
  3. Setup MultiTypeAdapter and register types

    master

    To use MultiType in your Activity or Fragment:

    1. Instantiate a MultiTypeAdapter.
    2. Register your delegates using adapter.register(Delegate()).
    3. Assign the adapter to your RecyclerView.
    4. Set the data using adapter.items = list and call adapter.notifyDataSetChanged().
    class SampleActivity : AppCompatActivity() {
    
      private val adapter = MultiTypeAdapter()
      private val items = ArrayList<Any>()
    
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_list)
        val recyclerView = findViewById<RecyclerView>(R.id.list)
    
        adapter.register(TextItemViewDelegate())
        adapter.register(ImageItemViewDelegate())
        adapter.register(RichItemViewDelegate())
        recyclerView.adapter = adapter
    
        val textItem = TextItem("world")
        val imageItem = ImageItem(R.mipmap.ic_launcher)
        val richItem = RichItem("小艾大人赛高", R.drawable.img_11)
    
        for (i in 0..19) {
          items.add(textItem)
          items.add(imageItem)
          items.add(richItem)
        }
        adapter.items = items
        adapter.notifyDataSetChanged()
      }
    }
  4. Use One-to-Many mapping for a single data type

    master

    You can register multiple delegates for a single data class using the .to() method. This allows you to decide which delegate to use at runtime based on the data content using withKotlinClassLinker.

    adapter.register(Data::class).to(
      DataType1ViewDelegate(),
      DataType2ViewDelegate()
    ).withKotlinClassLinker { _, data ->
      when (data.type) {
        Data.TYPE_2 -> DataType2ViewDelegate::class
        else -> DataType1ViewDelegate::class
      }
    }
  5. Implement ViewDelegate for custom Views

    master

    If you are using custom Views instead of XML layouts, you can use ViewDelegate. This is a simplified version of ItemViewDelegate that does not require you to manually declare and provide a RecyclerView.ViewHolder.

    class FooViewDelegate : ViewDelegate<Foo, FooView>() {
    
      override fun onCreateView(context: Context): FooView {
        return FooView(context).apply { layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT) }
      }
    
      override fun onBindView(view: FooView, item: Foo) {
        view.imageView.setImageResource(item.imageResId)
        view.textView.text = item.text
      }
    }
  6. Implement ItemViewDelegate for XML layouts

    master

    To handle a specific data type in a RecyclerView, extend ItemViewDelegate<T, VH : ViewHolder>. You must implement onCreateViewHolder to inflate the view and onBindViewHolder to bind the data to the view holder.

    Example implementation for a Foo data class:

    class FooViewDelegate: ItemViewDelegate<Foo, FooViewDelegate.ViewHolder>() {
    
      override fun onCreateViewHolder(context: Context, parent: ViewGroup): ViewHolder {
        return ViewHolder(FooView(context))
      }
    
      override fun onBindViewHolder(holder: ViewHolder, item: Foo) {
        holder.fooView.text = item.value
      }
    
      class ViewHolder(itemView : View): RecyclerView.ViewHolder(itemView) {
        val fooView: TextView = itemView.findViewById(R.id.foo)
      }
    }
  7. Override ItemViewDelegate lifecycle methods

    master

    The ItemViewDelegate class provides several open methods you can override to manage view lifecycle and data binding:

    • onBindViewHolder(holder: VH, item: T, payloads: List<Any>): Bind data to the holder (supports partial updates via payloads).
    • getItemId(item: T): Long: Return a unique ID for the item.
    • onViewRecycled(holder: VH): Called when the view is recycled.
    • onFailedToRecycleView(holder: VH): Boolean: Determine if recycling should be prevented.
    • onViewAttachedToWindow(holder: VH): Called when the view is attached to the window.
    • onViewDetachedFromWindow(holder: VH): Called when the view is detached from the window.