androidkotlinandroid-databindingandroid-binding-adapter

Android Binding Adapter using same binding name on same View type but for different purpose


First, I am new to data binding so please don't judge me for my (possibly dumb) question :). I want to use the same binding name for e.g app:data to a RecyclerView and bind it to a ViewModel field which provides a List<MyModel>. But, I want to use a different Adapter (to inflate different item layout for e.g) for a different instance of RecyclerView.

// For RecyclerView 1
@BindingAdapter("app:data")
fun setData(recyclerView: RecyclerView, data: List<MyModel>?) {
    data?.let {
        recyclerView.adapter = RV1Adapter(data)
    }
}

// For RecyclerView 2
@BindingAdapter("app:data")
fun setData(recyclerView: RecyclerView, data: List<MyModel>?) {
    data?.let {
        recyclerView.adapter = RV2Adapter(data)
    }
}

On a layout for e.g

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rcv1"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    app:data="${viewModel.data}"/>


<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rcv2"
    android:layout_width="match_parent"
    android:layout_height="300dp"
    app:data="${viewModel.data}"/>

How can I achieve this?

Should I use different binding name? (I'm not using this approach before because it will be a little bit messy I think)

Or how is the 'correct' way to do this?

Thank you 🙏


Solution

  • You can't use the same binding adapter tag as both setData() methods have the same signature/parameters, so in layout it can't decide which one to use.

    But instead you can use a single method, and differ between both RecyclerViews with their id

    @BindingAdapter("app:data")
    fun setData(recyclerView: RecyclerView, data: List<MyModel>?) {
        data?.let {
            if (recyclerView.id == R.id.rcv1)
                recyclerView.adapter = RV1Adapter(data)
    
            else if (recyclerView.id == R.id.rcv2)
                recyclerView.adapter = RV2Adapter(data)
        }
    }