【发布时间】:2022-11-07 13:08:36
【问题描述】:
为什么android开发人员的这个codelab传递一个“onNextButtonClicked:()->单元”,而不是仅仅传递“navController:NavController,”......看起来更简单......有这个原因吗?
【问题讨论】:
标签: android android-jetpack-compose
为什么android开发人员的这个codelab传递一个“onNextButtonClicked:()->单元”,而不是仅仅传递“navController:NavController,”......看起来更简单......有这个原因吗?
【问题讨论】:
标签: android android-jetpack-compose
将导航控制器传递到屏幕不是一个好习惯,这是以前的答案之一。
测试写作: 当你通过回调到最高级别达到你想要的命令时;您现在可以轻松编写测试,并且不需要模拟导航控制器。
因此,只有通过检查您使用过的回调,您才能确保可组合项功能的正确性。
考虑以下示例:
后屏幕
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
@Composable
fun PostScreen(
navigateToPostDetail: (PostId: PostId) -> Unit
) {
val posts = remember {
mutableListOf<Post>().apply {
repeat(10) {
add(
Post(
id = "$it", title = "Title $it"
)
)
}
}
}
PostScreenContent(
posts = posts,
navigateToPostDetail = navigateToPostDetail
)
}
data class Post(
val id: String, val title: String
)
@Composable
internal fun PostScreenContent(
posts: List<Post>,
navigateToPostDetail: (PostId: PostId) -> Unit
) {
LazyColumn {
items(items = posts, key = { item -> item.id }) { item ->
Text(text = item.title)
Button(onClick = {
navigateToPostDetail(PostId(item.id))
}
) {
Text(text = "Navigate To Detail")
}
}
}
}
@JvmInline
value class PostId(val value: String)
屏幕后测试
import androidx.activity.ComponentActivity
import androidx.compose.runtime.remember
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import org.junit.Rule
import org.junit.Test
internal class PostScreenTest {
@get:Rule
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
@Test
fun clickOnPostItem() {
var expectedPostId = "your expected id"
var actualPostId: String
with(composeTestRule) {
setContent {
val posts = remember {
mutableListOf<Post>().apply {
repeat(10) {
add(
Post(
id = "$it",
title = "Title $it"
)
)
}
}
}
PostScreenContent(
posts = posts,
navigateToPostDetail = {
actualPostId = it.value
}
)
}
assertThat(actualPostId).isEqualTo(expectedPostId)
}
}
}
但是,如果你想测试整个应用的导航逻辑,测试你的最高层,你使用 NavHost 的地方就足够了。
【讨论】:
这称为状态提升。您可以在official documentation 上阅读更多内容。
不过,快速回答您的问题:您提到的方式将起作用。但是通过hoisting 状态——也就是说,将可组合的状态移动到可组合之外并将其进一步向上推,通过使可组合stateless 可以使组件更容易重用和测试!
【讨论】: