Reputation: 1300
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.
I have an Adapter
(extends RecyclerView.Adapter
) for a RecyclerView
showing a list of BluetoothDevice
s. 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
}
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
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
Reputation: 1314
You can just have a method, for example onSomeClick()
in your class, and call it like this: android:onClick="@{onSomeClick}"
Upvotes: 1