Common Mistakes and Misuses of LazyColumn in Jetpack Compose
Ahmet Bostanciklioglu
Android Kotlin Developer | Jetpack Compose | iOS Swift | KMM | CMP
When we are using LazyColumn in the project. It is helping much us for listing items as vertically and adding scroll to list as automatic way, and it is making Android developer of developing much less than RecyclerView component. But sometimes using LazyColumn has some issues or bugs in the projects.
The first error is that nested scrolling error:
LazyColumn {
item {
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
) {
}
}
}
The error happened because of adding .verticalScroll(rememberScrollState()) to Column which is that used in the LazyColumn.
You can solve this error with two way:
The First solution way:
For nested scrolling error adding exact height value will solve the issue.
For example:
LazyColumn {
item {
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
.height(200.dp) //add this code
) {
}
}
}
It will inform the LazyColumn the inner Column has exact height and the code will crash at runtime because of the vertical scroll error.
The second solution way is that:
LazyColumn {
item {
Column(
modifier = Modifier
.fillMaxWidth()
//verticalScroll object is deleted
) {
}
}
}
In the second solution way the problem is solved with deleting verticalScroll object because in LazyColumn has vertical scroll in itself as default.
The second error is that scroll state in LazyColumn:
When we change items of states in LazyColumn and later when we scroll LazyColumn the changed states is not kept in LazyColumn to solve this issue let's we look at the below example:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyScreen()
}
}
}
@Composable
fun MyScreen() {
// you can change with your data the itemStates
val itemStates = remember { mutableStateListOf(1, 2, 3, 4, 5 ) }
LazyColumn {
itemsIndexed(itemStates) { index, state ->
MyItem(state) { newState ->
itemStates[index] = newState
}
}
}
}
@Composable
fun MyItem(state: Int, onStateChange: (Int) -> Unit) {
var currentState by remember { mutableStateOf(state) }
LaunchedEffect(state) {
currentState = state
}
Column {
Text("Current State: $currentState")
Button(onClick = { onStateChange(currentState + 1) }) {
Text("Increase State")
}
}
}
When we click the button the current state is changing and then this change will assign to the selected index of state. and when the itemStates change the with the LaunchedEffect(state) currentState is changing and ui will be updated with recomposition and when the LazyColumn is scrolled the updated state will be kept in UI(user interface).
Happy Coding. ??