在可组合函数的调用中“it”来自哪里?

问题描述 投票:0回答:1

我从 Android Developers Codelab 找到了一个代码示例,它涉及 Jetpack Compose 中的导航,它是“Rally Material Study”,代码位于 GitHub 上:NavigationCodeLab

尽管我最初想专注于导航,但我很难理解一些函数调用和 lambda。

在“OverviewScreen”可组合项中,“AccountsCard”被称为:

//other composable code

AccountsCard(
            onClickSeeAll = onClickSeeAllAccounts,
            onAccountClick = onAccountClick
        )

//other composable code

AccountsCard
定义如下:

private fun AccountsCard(onClickSeeAll: () -> Unit, onAccountClick: (String) -> Unit) {
    val amount = UserData.accounts.map { account -> account.balance }.sum()
    OverviewScreenCard(
        title = stringResource(R.string.accounts),
        amount = amount,
        onClickSeeAll = onClickSeeAll,
        data = UserData.accounts,
        colors = { it.color },
        values = { it.balance }
    ) { account ->
        AccountRow(
            modifier = Modifier.clickable { onAccountClick(account.name) },
            name = account.name,
            number = account.number,
            amount = account.balance,
            color = account.color
        )
    }
}

注意

colors = {it.color}
values = {it.balance}
- 这基本上是我正在努力解决的问题。

UserData 使用“假用户数据”定义了一些对象,其中使用

Account
类:

@Immutable
data class Account(
    val name: String,
    val number: Int,
    val balance: Float,
    val color: Color
)

UserData.accounts
是一个带有虚假数据的
List<Account>

AccountRow
定义如下:

@Composable
fun AccountRow(
    modifier: Modifier = Modifier,
    name: String,
    number: Int,
    amount: Float,
    color: Color
) {
    BaseRow(
        modifier = modifier,
        color = color,
        title = name,
        subtitle = stringResource(R.string.account_redacted) + AccountDecimalFormat.format(number),
        amount = amount,
        negative = false
    )
}

OverviewScreenCard

@Composable
private fun <T> OverviewScreenCard(
    title: String,
    amount: Float,
    onClickSeeAll: () -> Unit,
    values: (T) -> Float,
    colors: (T) -> Color,
    data: List<T>,
    row: @Composable (T) -> Unit
) {
    Card {
        Column {
            Column(Modifier.padding(RallyDefaultPadding)) {
                Text(text = title, style = MaterialTheme.typography.subtitle2)
                val amountText = "$" + formatAmount(
                    amount
                )
                Text(text = amountText, style = MaterialTheme.typography.h2)
            }
            OverViewDivider(data, values, colors)
            Column(Modifier.padding(start = 16.dp, top = 4.dp, end = 8.dp)) {
                data.take(SHOWN_ITEMS).forEach { row(it) }
                SeeAllButton(
                    modifier = Modifier.clearAndSetSemantics {
                        contentDescription = "All $title"
                    },
                    onClick = onClickSeeAll,
                )
            }
        }
    }
}

BaseRow
相当长,我现在跳过它,因为它本质上“只是”定义可组合项的实际外观,我也省略了
OverViewDivider
,因为我认为它无助于澄清。

我的理解是从

OverviewScreen
开始调用
AccountsCard
AccountsCard
本身调用
OverviewScreenCard
并提供所需的参数,其中包括作为列表的 UserData.accounts,其中
OverviewScreeCard
然后获取 SHOWN_ITEMS (= 3) 项并迭代它们,每个项都调用可组合项传入
row
,而
AccountsCard
又作为
AccountRow
传递。这就是我迷失方向的地方。

我对 lambda 做了一些工作,但仍有很多东西需要理解,我想这里就是这种情况。所以我假设对

account ->
的调用中的
AccountRow
是来自
it
.forEach
it
,前三个帐户中的每一个都作为参数传递给 AccountRow 并用于构建该行。

it
colors = {it.color}
中的
values = {it.balance}
从哪里来?

kotlin lambda android-jetpack-compose
1个回答
0
投票

it
colors = {it.color}
中的
values = {it.balance}
从哪里来?

OverviewScreenCard()
将这些参数定义为带有参数的函数类型:

    values: (T) -> Float,
    colors: (T) -> Color,

无论您为

values
colors
提供什么 lambda 表达式或其他函数类型,都可以使用
it
来引用该参数。或者,如果您愿意,您可以给它一个名称:

        colors = { account -> account.color },
        values = { account -> account.balance }

泛型

T
将由 Kotlin 编译器推断,主要是通过传递到
row
槽参数的类型来推断。在使用
OverviewScreenCard()
时,您传入的是
Account
,只要传入参数是
colors
values
Account
能够编译,Kotlin 编译器就会满意。

我还省略了 OverViewDivider,因为我认为它无助于澄清

它正在消耗

values
colors
。因此,“传递给这些 lambda 的实际参数值来自哪里”的问题由
OverViewDivider()
实现来回答,这不是您问题的一部分。

© www.soinside.com 2019 - 2024. All rights reserved.