https://kotlinlang.org logo
#compose
Title
# compose
n

natario1

02/27/2021, 7:23 PM
Is it possible to nest a LazyColumn in a scrollable Column? Like a RecyclerView with
height="wrap_content"
.
d

Dominaezzz

02/27/2021, 7:36 PM
This was made possible recently iirc.
a

Adam Powell

02/27/2021, 8:00 PM
You probably don't want to, as it defeats the lazy optimizations and turns LazyColumn into a very expensive for loop. 🙂 The LazyColumn DSL is probably better for the use case
(for all of the same reasons why RecyclerView in a ScrollView has conceptual challenges)
n

natario1

02/27/2021, 8:10 PM
I am aware of that, I just wanted to know if this setup still crashes (I'm still on alpha something), looks like no? "The LazyColumn DSL is probably better for the use case" what do you mean?
a

Adam Powell

02/27/2021, 8:40 PM
You can define several groups of items in the same lazy container:
Copy code
LazyColumn {
  item { Header(...) }
  items(...) { /* repeating items */ }
  // etc.
}
this will let all of those UI elements participate in the lazy behavior, so that it doesn't compose the entire contents of a LazyColumn at once
n

natario1

03/01/2021, 11:39 AM
I might be missing something, but I think it works great only when you have a single header or so - often in real life you'll have header, subheader, title, subtitle, description, big list, list footer, divider, image, maybe another list. Using a single LazyColumn here is messy. For example, you might want to use
Arrangement.spacedBy(32.dp)
for top level elements, and
Arrrangement.spacedBy(16.dp)
for inner lists. A different background, whatever. I know that I can just use Column, but still... The code also starts to look very weird IMO, as semantically what you have is "some headers, a list, a footer in a scrollable column" but what your code says is "a single list of mixed content". It looks to me like compose still needs to provide a proper solution to this (I don't know how - maybe nested LazyColumns could communicate with root LazyColumn through locals and be flattened under the hood, maybe at least
items
could accept modifiers and arrangement...)
BTW to answer my original question, nesting LazyColumn into something that scrolls is still impossible in beta01 (
Nesting scrollable in the same direction layouts like ScrollableContainer and LazyColumn 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().
)
a

Adam Powell

03/01/2021, 3:07 PM
The different content sections can be abstracted and named as extension functions of LazyListScope, e.g.:
Copy code
LazyColumn(...) {
  header(...)
  header(...)
  promotedItems(...)
  searchResultItems(...)
  footer(...)
}
Some future feature might set up a subcomposition of the list contents as a different composition tree type, but I'd prefer to wait and see before adding something that complex. I'd want to see a variety of examples where the DSL style above isn't sufficient first.
n

natario1

03/01/2021, 3:47 PM
There's still a big difference IMO.
@Composable fun LazyListScope.promotedItems()
works for splitting code in semantically reasonable sections, but the composable alone doesn't incapsulate all of the display logic! Like composables typically do. For example, it knows nothing about the spacing between items, controlled by `LazyColumn`'s arrangement, and any other
LazyColumn
modifier prop. So
promotedItems()
might add spacing with spacers (which is already annoying), but then the caller LazyColumn defines more spacing through the arrangement and the UI is messed up. The result is that
promotedItems()
is not really a reusable component - there's a hidden dependency with the parent modifier and props. It's like
LazyListScope.promotedItems()
is a RecyclerView.Adapter, who doesn't know about the RecyclerView background, decorations, padding, touch handling, none of this. This would be acceptable if there was a way to make this dependency explicit, e.g. pass stuff to
promotedItems()
and then to
items(modifier,...) { }
, but items has no modifier as we know. About "variety of examples where the DSL style above isn't sufficient", if you want to start by collecting mine, basically everything that refers to the sublist as a whole is very tricky, impossible or a stretch. Think of giving the sublist (list minus header) a non-trivial background, for example. Padding, spacing, a click listener for the list as a whole...
1
a

Adam Powell

03/01/2021, 3:58 PM
sure, happy to keep the feature requests tracked in the issue tracker if you'd like to add them 🙂
9 Views