RecylerView with databinding

 It is very easy to create RecyclerView with Databinding.


Step 1: - First you have to Enable DataBinding by giving following code in gradle file :- 


android {
compileSdkVersion 29
buildToolsVersion "29.0.3"

defaultConfig {
applicationId "com.blizle"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

dataBinding {
enabled = true
}

lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}

To enable data-binding you have to specify
 dataBinding {
enabled = true
}

Then add some more libraries for data-binding, as followiing.

def life_versions = "1.1.1"
implementation "android.arch.lifecycle:extensions:$life_versions"
annotationProcessor "android.arch.lifecycle:compiler:$life_versions"
implementation 'com.android.support:multidex:1.0.3'
implementation 'com.android.databinding:compiler:1.0-rc0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'

Now all set for data-binding.

Step :- 

Add Library for ReceyclerView and add tag RecyclerView in XML file :- 

<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
recyclerAdapter="@{mainViewModel.adapter}"
tools:listitem="@layout/adapter_layout"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

After that create Recycler Adapter and its ViewModel all the click that you want to 
perform then you can manage those clicks in adapter's ViewModel.

RecyclerView Adapter :-

class Adapter(var context: Context) : RecyclerView.Adapter<Adapter.ViewHolder>() {

var list: ArrayList<MainVIewModel.ListModel> = ArrayList()

fun update(ls:ArrayList<MainVIewModel.ListModel>) {
list.clear()
list.addAll(ls)
notifyDataSetChanged()
}

inner class ViewHolder(var adapterLayoutBinding: AdapterLayoutBinding) :
RecyclerView.ViewHolder(adapterLayoutBinding.root) {

fun setData(listModel: MainVIewModel.ListModel) {
try {
val adapterViewModel = AdapterVM(context, listModel)
adapterLayoutBinding.adapterVm = adapterViewModel
adapterLayoutBinding.executePendingBindings()
}catch (e:Exception) {
e.printStackTrace()
}
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val adapterLayoutBinding = AdapterLayoutBinding.inflate(LayoutInflater.from(context), parent, false)
return ViewHolder(adapterLayoutBinding)
}

override fun getItemCount(): Int {
return list.size
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.setData(list[position])
}
}

And create Another class for recycler adapter's ViewModel as Following :- 
class AdapterVM(var context: Context, var listModel: MainVIewModel.ListModel) 

Now Create Binding Adapter to set Recycler Adapter :-

if there is any problem or error with @BindingAdapter(value = ["recyclerAdapter"], requireAll = false)
this line then make sure you have declare 'id kotlin-lapt'  in your gradle file

import android.graphics.drawable.Drawable
import android.widget.ImageView
import androidx.databinding.BindingAdapter
import androidx.recyclerview.widget.RecyclerView

object BindingAdapter {

@BindingAdapter(value = ["recyclerAdapter"], requireAll = false)
@JvmStatic
fun recyclerAdapter(recyclerView: RecyclerView, adapter: RecyclerView.Adapter<*>) {
recyclerView.adapter = adapter
}

@BindingAdapter(value = ["setPhoto"], requireAll = false)
@JvmStatic
fun setPhoto(imageView: ImageView, drawable: Int) {
imageView.setBackgroundResource(drawable)
}
}

And you also have to create ViewModel class for main class and factory class to pass parameters.

 MainActivity :-

class MainActivity : AppCompatActivity() {

var activityMainBinding: ActivityMainBinding?=null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
val mainFactory = MainFactory(this)
val activityViewModel = ViewModelProvider(this, mainFactory).get(MainVIewModel::class.java)
activityMainBinding!!.mainViewModel= activityViewModel
}
}

Create ViewModel for main class:-

class MainVIewModel(var context: Context) : ViewModel() {

var list: ArrayList<ListModel> = ArrayList()
var adapter: Adapter?=null


init {
list.add(ListModel(R.drawable.car1, "Car 1"))
list.add(ListModel(R.drawable.car2, "Car 2"))
list.add(ListModel(R.drawable.car3, "Car 3"))
list.add(ListModel(R.drawable.cars4, "Car 4"))
list.add(ListModel(R.drawable.cars5, "Car 5"))
adapter = Adapter(context)
adapter!!.update(list)
}


data class ListModel(
var image: Int,
var title: String = ""
)
}

Create Factory for main class and viewmodel :-

class MainFactory(var context: Context) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainVIewModel::class.java)) {
return MainVIewModel(context) as T
}
throw IllegalArgumentException("unKnow Error")
}
}


Now all set you have Create recycler Adapter with databinding.

















0 Comments