Hel*_*oCW 5 kotlin android-jetpack-compose
代码A来自官方示例项目的主分支。
项目中有三个枚举类的子类Overview
,Accounts
和。Bills
RallyScreen
类中有一个fun content(onScreenChange: (String) -> Unit) { body(onScreenChange) }
接受参数的函数。onScreenChange : (String) -> Unit
RallyScreen
虽然说法是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
。在body
lambda中,指的是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可组合项。目前没有与该可组合项相对应的。因此,您必须创建一个新的枚举值,如下所示:RallyScreen
RallyScreen
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 传递此信息。Overview
SingleAccount
accountName
归档时间: |
|
查看次数: |
263 次 |
最近记录: |