## BindingListAdapter ![](https://img.shields.io/badge/minSdk-14-brightgreen.svg) ![](https://img.shields.io/badge/version-1.0.3-green.svg) ![](https://img.shields.io/badge/recyclerview_version-28.0.0-blue.svg) ![](https://img.shields.io/badge/kotlin_version-1.3.11-blue.svg) ![](https://img.shields.io/badge/androidx_support-true-green.svg) Say goodbye to repeated, redundant custom Adapters , Make the developer's focus on the data, beacuse data-driven UI ### demo https://fabu.love/7me2fm ### Example ![singletype](gif/singletype.gif) ![multitype](gif/multitype.gif) #### more PaoNet : [https://github.com/ditclear/paonet](https://github.com/ditclear/paonet) ### Download ```groovy implementation 'com.ditclear:bindinglistadapter:1.0.1' // if you use androidx implementation 'com.ditclear:bindinglistadapterx:1.0.0' ``` ### Quick Start creating a single-type RecyclerView.Adapter with only a simple 3 step 1. Create a `list-item.xml` file in databinding form for Item ```xml ``` 2. Create our `dataSource` and `SingleTypeAdapter` in `Activity/Fragment` file ```kotlin val dataSource=ObservableArrayList() //typically in the ViewModel layer val mAdapter by lazy { SingleTypeAdapter(this, R.layout.list_item, dataSource) .apply{ itemPresenter=this@currentActity } } ``` 3. set `adapter` for `recyclerView` ```kotlin recyclerView.apply{ adapter = mAdapter layoutManager = LinearLayoutManager(context) } ``` Over, you're done. Then just change the data source ```kotlin //add item dataSource.add(item) //remove item dataSource.remove(item) // or dataSource.removeAt(indexOfItem) //setNewList dataSource.clear() dataSource.addAll(newList) //batch remove dataSouce.removeRange(startIndex ,offset) //kotin extension //and so on ``` #### Why? The Android DataBinding framework provides the `ObservableArrayList` class, which provides several callbacks corresponding to RecyclerView.Adapter. ```kotlin dataSource.addOnListChangedCallback(object : ObservableList.OnListChangedCallback>() { override fun onChanged(contributorViewModels: ObservableList) { notifyDataSetChanged() } override fun onItemRangeChanged(contributorViewModels: ObservableList, i: Int, i1: Int) { notifyItemRangeChanged(i, i1) } override fun onItemRangeInserted(contributorViewModels: ObservableList, i: Int, i1: Int) { notifyItemRangeInserted(i, i1) } override fun onItemRangeMoved(contributorViewModels: ObservableList, i: Int, i1: Int, i2: Int) { notifyItemMoved(i, i1) } override fun onItemRangeRemoved(contributorViewModels: ObservableList, i: Int, i1: Int) { if (contributorViewModels.isEmpty()) { notifyDataSetChanged() } else { notifyItemRangeRemoved(i,i1) } } }) ``` ### Usage Provides [SingleTypeAdapter](library-kotlin/src/main/java/io/ditclear/bindingadapter/SingleTypeAdapter.kt) and [MultiTypeAdapter](library-kotlin/src/main/java/io/ditclear/bindingadapter/MultiTypeAdapter.kt) - **SingleTypeAdapter** ```kotlin val dataSource=ObservableArrayList() val mAdapter by lazy { SingleTypeAdapter(this, R.layout.list_item, dataSource) } ``` - **MultiTypeAdapter** ```kotlin val dataSource=ObservableArrayList() val mAdapter by lazy { MultiTypeAdapter(this, dataSource, object : MultiTypeAdapter.MultiViewTyper { override fun getViewType(item: Any): Int = when(item){ //return Item View type is ItemWrapper -> item.type is String -> ItemType.TYPE_5 else -> throw Resources.NotFoundException("${item::class} has not found it's ViewType") } }).apply { addViewTypeToLayoutMap(ItemType.TYPE_0, R.layout.multi_type_0) addViewTypeToLayoutMap(ItemType.TYPE_1, R.layout.multi_type_1) addViewTypeToLayoutMap(ItemType.TYPE_2, R.layout.multi_type_2) addViewTypeToLayoutMap(ItemType.TYPE_3, R.layout.multi_type_3) addViewTypeToLayoutMap(ItemType.TYPE_4, R.layout.multi_type_4) addViewTypeToLayoutMap(ItemType.TYPE_5, R.layout.multi_type_5) } } ``` ### Click Event [ItemClickPresenter](library-kotlin/src/main/java/io/ditclear/bindingadapter/ItemClickPresenter.kt) is provided to handle click events ```kotlin //single type : According to the viewId to distinguish override fun onItemClick(v: View, item: String) { Toast.makeText(this,item,Toast.LENGTH_SHORT).show() } //multi type : According to the viewId or item's type to distinguish override fun onItemClick(v: View, item: Any) { when(item){ is ItemWrapper -> Toast.makeText(this, item.bean, Toast.LENGTH_SHORT).show() is String -> Toast.makeText(this, item.split("").reversed().joinToString(""), Toast.LENGTH_SHORT).show() } } ``` in `list_item.xml` ,We need to bind the click event ```xml ``` ### ItemDecorator If the above cannot meet the requirements, additional settings can be made by setting [ItemDecorator](library-kotlin/src/main/java/io/ditclear/bindingadapter/ItemDecorator.kt) ```kotlin override fun decorator(holder: BindingViewHolder, position: Int, viewType: Int) { //do sth.. } ``` Similar to `onBindViewHolder` method ### Thanks To [markzhai](https://github.com/markzhai)/[DataBindingAdapter](https://github.com/markzhai/DataBindingAdapter) ### License [MIT](LICENSE.txt)