notquiteamonad
notquiteamonad

Reputation: 1169

How should a composable higher order function be referenced with Jetpack Compose?

I'm using Jetpack Compose version 0.1.0-dev13

I've written a simple composable function which uses an AdapterList with a list of items. (Note: this works as intended when using a lambda instead of a reference using the :: syntax)

AdapterList(data = items, itemCallback = ::ItemCard)

For reference, the signature of AdapterList is as follows:

@Composable
fun <T> AdapterList(
    data: List<T>,
    modifier: Modifier = Modifier,
    itemCallback: @Composable (T) -> Unit
)

In the interest of better facilitating individual previews, I've factored the item callback out into a separate composable function.

The ItemCard function looks like this:

@Composable
private fun ItemCard(item: Item) {
    Card(
        color = item.type.getColor()
    ) {
        Text(
            item.name,
            style = MaterialTheme.typography.h5
        )
    }
}

It is my understanding that the ItemCard function has a signature of @Composable (Item) -> Unit which should satisfy the type of the itemCallback parameter of AdapterList.

No error shows in the IDE at this point.

However, when trying to build the project, the following error is displayed:

Type mismatch: inferred type is KFunction1<Item, Unit> but (Item) -> Unit was expected

What is the difference between the two types and how should ItemCard (or the reference to it) be changed to satisfy the type constraints?

Upvotes: 5

Views: 4427

Answers (2)

CommonsWare
CommonsWare

Reputation: 1006674

OK, the preliminary analysis is: it's a bug.

(note: the link in preceding paragraph requires Kotlinlang Slack access)

I filed an issue for this (which was subsequently marked as a duplicate of this issue). So, in the meantime, you are stuck with lambda expressions. But, keep tabs on the issue, as it's possible that we will find out about a workaround there.

Upvotes: 3

Gabriele Mariotti
Gabriele Mariotti

Reputation: 363785

You can use:

AdapterList(data = items){ ItemCard(item = it) }

or

AdapterList(data = items, itemCallback= { ItemCard(it) } )

Upvotes: 1

Related Questions