Issue
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?
Solution
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 your Box
.
You can change your box implementation to this and it should work. I am using fillMaxSize
here
@Composable
fun SomeComposable(onClick: (Int) -> Unit) {
var someState by remember { mutableStateOf(0) }
Box(modifier = Modifier
.fillMaxSize()
.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"
// and then "LaunchedEffect someState 2"
if (someState == 2) {
onClick(someState)
}
}
}
Answered By - Rafsanjani
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.