Replace java generic interface in Kotlin for data binding
I got to know Kotlin as an Android developer. When building Android apps, I'm used to using Databinding, retrolambda, etc. Now I am a bit lost on how to solve the following case in Kotlin.
How i usually do it in java
I have Adapter
(extends RecyclerView.Adapter
) for a RecyclerView
displaying a list BluetoothDevice
s. Typically, all my projects have a common TypedClickListener interface that returns the T-object of the list that the user has clicked on. For example:
Common interface:
public interface TypedClickListener<T> {
void onClick(T t);
}
PairedDeviceAdapter constructor
public PairedDeviceAdapter(Context context, BluetoothDevice[] devices, TypedClickHandler<BluetoothDevice> handler){
mContext = context;
mDevices = devices
mClickHandler = handler;
}
Adapter onBindViewHolder: (holder contains data binding 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, all together:
Passing TypedClickListener to adapter in Activity:
mAdapter = PairedDeviceAdapter(this, devices, (bluetoothDevice) -> {
// The code that is ran when user clicks a device
}
How do I try to do it in Kotlin
As I said, I am trying to do this with Kotlin. It seems I can skip the step TypedClickListener
, as I can use a simple built-in function (BluetoothDevice) -> Unit
.
PairedDeviceAdapter looks like this:
class PairedDeviceAdapter(val context: Context, val clickHandler : (BluetoothDevice) -> Unit ) : RecyclerView.Adapter<DatabindViewHolder>() {
OnBindViewHolder looks the same as its Java version. However, I can't figure out how to bind my layout to the clicker as I don't have a click handler type.
<?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 create the same structure in Kotlin, or is there another (smarter?) Solution to bind a string-jumper to a lambda function defined in Activity
(or Fragment
).
source to share