When trying to put a LazyVerticalGrid
inside a scrollable Column
I get the following error:
java.lang.IllegalStateException: Nesting scrollable in the same direction layouts like LazyColumn and Column(Modifier.verticalScroll()) is not allowed. If you want to add a header before the list of items please take a look on LazyColumn component which has a DSL api which allows to first add a header via item() function and then the list of items via items().
I am not making a traditional list, I just have alot of elements that are too big to fit on the screen. Therefore I want the column to scroll so I can see all the elements. Here is my code:
@ExperimentalFoundationApi
@Composable
fun ProfileComposable(id: String?) {
val viewModel: ProfileViewModel = viewModel()
if (id != null) {
viewModel.getProfile(id)
val profile = viewModel.profile.value
val scrollState = rememberScrollState()
if (profile != null) {
Column(modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.verticalScroll(scrollState)) {
Row() {
ProfilePic(profile.getImgUrl(), profile.name)
Column(Modifier.padding(16.dp)) {
ProfileName(profile.name)
Stats(profile.stats) // <--------------- the offending composable
}
}
Sprites(sprites = profile.sprites)
TextStat(profile.id.toString(), "Pokemon Number")
TextStat(profile.species.name, "Species")
TextStat(profile.types.joinToString { it.type.name }, "Types")
TextStat(profile.weight.toString(), "Weight")
TextStat(profile.forms.joinToString { it.name }, "Forms")
}
} else {
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
CircularProgressIndicator()
}
}
} else {
Text("Error")
}
}
The Stats()
composable contains the LazyVerticalGrid
which causes the error:
@ExperimentalFoundationApi
@Composable
fun Stats(stats: List<Stat>) {
LazyVerticalGrid(cells = GridCells.Fixed(2)) {
itemsIndexed(stats) { index, item ->
StatBox(stat = item)
}
}
}
I do not want the grid to scroll, I just want to display a grid within a scrollable column.
We can make the Column scrollable by using the verticalScroll() modifier.
A LazyColumn is a vertically scrolling list that only composes and lays out the currently visible items. It's similar to a Recyclerview in the classic Android View system.
mutableStateOf creates an observable MutableState<T> , which is an observable type integrated with the compose runtime. interface MutableState<T> : State<T> { override var value: T } Any changes to value will schedule recomposition of any composable functions that read value .
Jetpack Compose is a modern toolkit designed to simplify UI development. It combines a reactive programming model with the conciseness and ease of use of the Kotlin programming language.
I just ran into this problem myself. As @gaohomway said, your best bet is to use the experimental FlowRow() from Google's Accompanist library.
Here is a working code snippet as an example:
@Composable
fun ProfileScreen2() {
LazyColumn(
modifier = Modifier
.fillMaxSize()
) {
item {
Box(modifier = Modifier.fillMaxWidth().height(200.dp).background(color = Red))
}
item {
Box(modifier = Modifier.fillMaxWidth().height(200.dp).background(color = Gray))
}
item {
FlowRow() {
SampleContent()
}
}
}
}
@Composable
internal fun SampleContent() {
repeat(60) {
Box(
modifier = Modifier
.size(64.dp)
.background(Blue)
.border(width = 1.dp, color = DarkGray),
contentAlignment = Alignment.Center,
) {
Text(it.toString())
}
}
}
Displays this scrollable page (don't mind the nav bar at the bottom):
I had a similar use-case, the goal was to design a profile screen that has a bunch of information and statistics on top, and then comes to the posts as a Grid in the bottom of the screen.
I ended up using the LazyVerticalGrid for the whole list and setting full span for the items that need to fill the entire screen:
LazyVerticalGrid(cells = GridCells.Fixed(3)) {
item(span = { GridItemSpan(3) }) { TopInfo() }
item(span = { GridItemSpan(3) }) { SomeOtherInfo() }
item(span = { GridItemSpan(3) }) { BottomInfo() }
items(gridItems) { GridItemView(it) }
}
Reason
Nesting scrollable in the same direction layouts like LazyColumn and Column(Modifier.verticalScroll()) is not allowed.
Can't find LazyVerticalGrid
forbidden scrolling temporarily
Alternatives
Alternative library from Android official Jetpack Compose Flow Layouts
FlowRow {
// row contents
}
FlowColumn {
// column contents
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With