Hel*_*oCW 5 kotlin android-jetpack-compose
代码A来自官方示例项目的主分支。
项目中有三个枚举类的子类Overview,Accounts和。BillsRallyScreen
类中有一个fun content(onScreenChange: (String) -> Unit) { body(onScreenChange) }接受参数的函数。onScreenChange : (String) -> UnitRallyScreen
虽然说法是enum class RallyScreen(val body: @Composable ((String) -> Unit) -> Unit) {..},body = { OverviewBody() }类中Overview、body = { AccountsBody(UserData.accounts) } 类中 Accounts、类body = { BillsBody(UserData.bills) }中Bills不需要传参(String) -> Unit),但是为什么Kotlin能运行良好,App启动时Tab导航也能很好呢fun content(onScreenChange: (String) -> Unit) { body(onScreenChange)}?
代码A
@Composable
fun RallyApp() {
RallyTheme {
val allScreens = RallyScreen.values().toList()
var currentScreen by rememberSaveable { mutableStateOf(RallyScreen.Overview) }
Scaffold(
topBar = {
RallyTabRow(
allScreens = allScreens,
onTabSelected = { screen -> currentScreen = screen },
currentScreen = currentScreen
)
}
) { innerPadding ->
Box(Modifier.padding(innerPadding)) {
currentScreen.content(
onScreenChange = { screen ->
currentScreen = RallyScreen.valueOf(screen)
}
)
}
}
}
}
enum class RallyScreen(
val icon: ImageVector,
val body: @Composable ((String) -> Unit) -> Unit
) {
Overview(
icon = Icons.Filled.PieChart,
body = { OverviewBody() }
),
Accounts(
icon = Icons.Filled.AttachMoney,
body = { AccountsBody(UserData.accounts) }
),
Bills(
icon = Icons.Filled.MoneyOff,
body = { BillsBody(UserData.bills) }
);
@Composable
fun content(onScreenChange: (String) -> Unit) {
body(onScreenChange)
}
}
@Composable
fun OverviewBody(
onClickSeeAllAccounts: () -> Unit = {},
onClickSeeAllBills: () -> Unit = {},
onAccountClick: (String) -> Unit = {},
) {
...
}
@Composable
fun AccountsBody(
accounts: List<Account>,
onAccountClick: (String) -> Unit = {},
) {
...
}
@Composable
fun BillsBody(bills: List<Bill>) {
...
}
Run Code Online (Sandbox Code Playgroud)
新增内容:
加布里埃尔·皮萨罗:谢谢!
根据声明clas Overview,body不需要任何参数,使用默认值,onScreenChange参数是如何传递的?
Overview(
icon = Icons.Filled.PieChart,
body = { OverviewBody() } //It needn't any parameter
)
@Composable
fun content(onScreenChange: (String) -> Unit) {
body(onScreenChange)
}
Run Code Online (Sandbox Code Playgroud)
而且,当我添加两个默认参数以获取乐趣时,该应用程序可以正常运行OverviewBody(...)。
@Composable
fun OverviewBody(
onClickSeeAllAccounts: () -> Unit = {},
onClickSeeAllBills: () -> Unit = {},
a1: (String) -> Unit = {}, // I add
onAccountClick: (String) -> Unit = {},
a2: (String) -> Unit = {}, //I add
) {
...
}
Run Code Online (Sandbox Code Playgroud)
也许
body = { OverviewBody() }应该body = { OverviewBody(onAccountClick = it) }去Overview上课吧?
事实上,不!
接收到的 lambdabody与 不同OverviewBody.onAccountClick。在bodylambda中,指的是String的名称,您可以从此处RallyScreen的用法中看到。在lambda中,代表一个 accountName。onAccountClick String
通过类的声明
Overview,body不需要任何参数,它使用默认值,onScreenChange参数是如何传递的?
onScreenChange没有在任何地方被调用,这就是导航不起作用的原因。
您可以SEE ALL使用以下方法使概览屏幕中的按钮正常工作:
Overview(
icon = Icons.Filled.PieChart,
body = {
OverviewBody(
onClickSeeAllAccounts = { it(Accounts.name) },
onClickSeeAllBills = { it(Bills.name) },
)
}
)
Run Code Online (Sandbox Code Playgroud)
onAccountClick中的 lambda处理OverviewBody起来很棘手。我们需要在单击AccountRow时显示SingleAccountBody可组合项。目前没有与该可组合项相对应的。因此,您必须创建一个新的枚举值,如下所示:RallyScreenRallyScreen
Overview(
icon = Icons.Filled.PieChart,
body = {
OverviewBody(
onClickSeeAllAccounts = { it(Accounts.name) },
onClickSeeAllBills = { it(Bills.name) },
onAccountClick = { accountName -> >>>>>>
it(SingleAccount.name) |
} |
) |
} |
), |
Accounts( |
icon = Icons.Filled.AttachMoney, |
body = { |
AccountsBody(UserData.accounts) |
} |
), |
Bills( |
icon = Icons.Filled.MoneyOff, |
body = { BillsBody(UserData.bills) } |
), |
SingleAccount( |
icon = Icons.Filled.AttachMoney, |
body = { |
SingleAccountBody(UserData.getAccount(???accountName???)) <<<--
}
);
Run Code Online (Sandbox Code Playgroud)
在这里,我们需要将从一个屏幕accountName接收到的信息发送到另一个屏幕以使导航正常工作。但在当前的代码结构中没有简单的方法可以做到这一点,我不想让这个答案变得太复杂。在此 Codelab 的最终代码中,已使用 NavArguments 传递此信息。OverviewSingleAccountaccountName
| 归档时间: |
|
| 查看次数: |
263 次 |
| 最近记录: |