@Composable functions are recomposed
- if one the parameters is changed or
- if one of the parameters is not @Stable/@Immutable
When passing items: List<Int>
as parameter, compose always recomposes, regardless of List
is immutable and cannot be changed. (List is interface without @Stable annotation). So any Composable function which accepts List<T>
as parameter always gets recomposed, no intelligent recomposition.
How to mark List<T>
as stable, so compiler knows that List is immutable and function never needs recomposition because of it?
Only way i found is wrapping like @Immutable data class ImmutableList<T>(val items: List<T>)
. Demo (when Child1 recomposes Parent, Child2 with same List gets recomposed too):
class TestActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeBasicsTheme {
Parent()
}
}
}
}
@Composable
fun Parent() {
Log.d("Test", "Parent Draw")
val state = remember { mutableStateOf(false) }
val items = remember { listOf(1, 2, 3) }
Column {
// click forces recomposition of Parent
Child1(value = state.value,
onClick = { state.value = !state.value })
//
Child2(items)
}
}
@Composable
fun Child1(
value: Boolean,
onClick: () -> Unit
) {
Log.d("Test", "Child1 Draw")
Text(
"Child1 ($value): Click to recompose Parent",
modifier = Modifier
.clickable { onClick() }
.padding(8.dp)
)
}
@Composable
fun Child2(items: List<Int>) {
Log.d("Test", "Child2 Draw")
Text(
"Child 2 (${items.size})",
modifier = Modifier
.padding(8.dp)
)
}
items
argument looks like, how you call it from another composable and what causes top function recomposition. – Nodical