在 Jetpack Compose 中进行 UI 测试时,Box 上未调用 LaunchedEffect
我正在对 LaunchedEffect 运行一个简单的测试:
@Test
fun testSomeState() {
composeTestRule.setContent {
SomeComposable {
println("click $it")
}
}
composeTestRule.onNodeWithTag("Zivi")
.performClick()
.assertExists()
}
@Composable
fun SomeComposable(onClick: (Int) -> Unit) {
var someState by remember { mutableStateOf(0) }
Button(modifier = Modifier.testTag("Zivi").pointerInteropFilter {
someState = when (it.action) {
MotionEvent.ACTION_DOWN -> { 1 }
MotionEvent.ACTION_UP -> { 2 }
else -> { someState }
}
true
}, onClick = { }) {}
LaunchedEffect(someState) {
println("LaunchedEffect someState $someState") // prints "LaunchedEffect someState 0"
// and then "LaunchedEffect someState 2"
if (someState == 2) { onClick(someState) }
}
}
这效果很好,但是,如果我将 Button 更改为 Box,如下所示:
@Composable
fun SomeComposable(onClick: (Int) -> Unit) {
var someState by remember { mutableStateOf(0) }
Box(modifier = Modifier.testTag("Zivi").pointerInteropFilter {
someState = when (it.action) {
MotionEvent.ACTION_DOWN -> { 1 }
MotionEvent.ACTION_UP -> { 2 }
else -> { someState }
}
true
}) {}
LaunchedEffect(someState) {
println("LaunchedEffect someState $someState") // prints "LaunchedEffect someState 0"
if (someState == 2) { onClick(someState) }
}
}
然后在 PerformClick 上不会调用 LaunchedEffect,任何人都可以帮助我理解为什么吗?
I am running a simple Test on LaunchedEffect:
@Test
fun testSomeState() {
composeTestRule.setContent {
SomeComposable {
println("click $it")
}
}
composeTestRule.onNodeWithTag("Zivi")
.performClick()
.assertExists()
}
@Composable
fun SomeComposable(onClick: (Int) -> Unit) {
var someState by remember { mutableStateOf(0) }
Button(modifier = Modifier.testTag("Zivi").pointerInteropFilter {
someState = when (it.action) {
MotionEvent.ACTION_DOWN -> { 1 }
MotionEvent.ACTION_UP -> { 2 }
else -> { someState }
}
true
}, onClick = { }) {}
LaunchedEffect(someState) {
println("LaunchedEffect someState $someState") // prints "LaunchedEffect someState 0"
// and then "LaunchedEffect someState 2"
if (someState == 2) { onClick(someState) }
}
}
This works well, however, if i change Button to a Box, like this:
@Composable
fun SomeComposable(onClick: (Int) -> Unit) {
var someState by remember { mutableStateOf(0) }
Box(modifier = Modifier.testTag("Zivi").pointerInteropFilter {
someState = when (it.action) {
MotionEvent.ACTION_DOWN -> { 1 }
MotionEvent.ACTION_UP -> { 2 }
else -> { someState }
}
true
}) {}
LaunchedEffect(someState) {
println("LaunchedEffect someState $someState") // prints "LaunchedEffect someState 0"
if (someState == 2) { onClick(someState) }
}
}
Then the LaunchedEffect is not called on performClick, can anyone help me understand why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
默认情况下,可组合框没有任何大小,因此从技术上讲,当用户单击屏幕的任何部分时,
Box
不会消耗该事件。您可以通过向框中添加
background(color = Color.Green)
修饰符来验证这一点,并观察屏幕的任何部分都不会按预期变为绿色。您可以通过为
Box
设置size
修饰符来解决此问题。您可以将您的盒子实现更改为此,它应该可以工作。我在这里使用
fillMaxSize
The box composable by default doesn't have any size so technically, when the user clicks on any portion of the screen, the event doesn't get consumed by the
Box
.You can verify this by adding a
background(color = Color.Green)
modifier to your box and observe that no section of the screen gets colored green as expected.You can fix this by setting a
size
modifier for yourBox
.You can change your box implementation to this and it should work. I am using
fillMaxSize
here