Marcel50506
Marcel50506

Reputation: 1300

Replace java generic interface in Kotlin for Databinding

I'm getting to know Kotlin as an Android developer. When making android apps, I'm used to using Databinding, retrolambda, etc. Now I'm a bit lost in how to solve the following case in Kotlin.

How I would normally do this in java

I have an Adapter (extends RecyclerView.Adapter) for a RecyclerView showing a list of BluetoothDevices. Normally, all my projects have a generic interface TypedClickListener, which will give back the T object of the listitem the user clicked on. Like so:

The generic interface:

public interface TypedClickListener<T> {
    void onClick(T t);
}

Constructor of PairedDeviceAdapter

public PairedDeviceAdapter(Context context, BluetoothDevice[] devices, TypedClickHandler<BluetoothDevice> handler){
    mContext = context;
    mDevices = devices
    mClickHandler = handler;
}

The adapter's onBindViewHolder: (the holder contains a databinding layout)

public void onBindViewHolder(DatabindViewHolder holder, Int position) {
    holder.getBinding().setVariable(BR.device, mDevices[position]);
    holder.getBinding().setVariable(BR.handler, mClickHandler);
}

The layout itself:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="android.bluetooth.BluetoothDevice"/>
        <import type="com.example.TypedClickHandler"/>
        <variable
            name="device"
            type="BluetoothDevice"/>
        <variable
            name="handler"
            type="TypedClickHandler"/>
    </data>
    <LinearLayout
        ... // width, height, etc
        android:onClick="@{v->handler.onClick(device)}">
        ... // Row layout etc
    </LinearLayout>
</layout>

Now, putting everything together:

Passing the TypedClickListener to the Adapter in the Activity:

mAdapter = PairedDeviceAdapter(this, devices, (bluetoothDevice) -> {
    // The code that is ran when user clicks a device
}

How I'm trying to do this in Kotlin

As said, I'm trying to do this with Kotlin. It seems I can skip the step of having a TypedClickListener, since I can use a simple inline function (BluetoothDevice) -> Unit.

The PairedDeviceAdapter looks like this:

class PairedDeviceAdapter(val context: Context, val clickHandler : (BluetoothDevice) -> Unit ) : RecyclerView.Adapter<DatabindViewHolder>() {

The onBindViewHolder looks kinda the same as the Java version of it. However, I can't figure out how to bind my layout to the clickhandler, since I don't have the type of the clickhandler.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="android.bluetooth.BluetoothDevice"/>
        <import type="???"/>
        <variable
            name="device"
            type="BluetoothDevice"/>
        <variable
            name="handler"
            type="???"/>
    </data>
    <LinearLayout
        ...
        android:onClick="@{v->handler.???(device)}">
        ... // close everything

Question

How can I make this same structure in Kotlin, or is there another (smarter?) solution to binding a adapter-row-click to a lambda function defined in the Activity (or Fragment).

Upvotes: 3

Views: 1120

Answers (1)

John
John

Reputation: 1314

You can just have a method, for example onSomeClick() in your class, and call it like this: android:onClick="@{onSomeClick}"

Upvotes: 1

Related Questions