It’s supposed to re-measure a component based on another component size…
SubcomposeLayout
doesn’t remeasure. It allows deferring the composition and measure of content until its constraints from its parent are known and some its content can be measured, the results from which and can be passed as a parameter to the deferred content. The above example calculates the maximum size of the content generated by mainContent
and passes it as a parameter to deferredContent
. It then measures deferredContent
and places both mainContent
and deferredContent
on top of each other.
The simplest example of how to use SubcomposeLayout
is BoxWithConstraints that just passes the constraints it receives from its parent directly to its content. The constraints of the box are not known until the siblings of the box have been measured by the parent which occurs during layout so the composition of content
is deferred until layout.
Similarly, for the example above, the maxSize
of mainContent
is not known until layout so deferredContent
is called in layout once maxSize
is calculated. It always places deferredContent
on top of mainContent
so it is assumed that deferredContent
uses maxSize
in some way to avoid obscuring the content generated by mainContent
. Probably not the best design for a composable but the composable was intended to be illustrative not useful itself.
Note that subcompose
can be called multiple times in the layout
block. This is, for example, what happens in LazyRow
. The slotId
allows SubcomposeLayout
to track and manage the compositions created by calling subcompose
. For example, if you are generating the content from an array you might want use the index of the array as its slotId
allowing SubcomposeLayout
to determine which subcompose
generated last time should be used to during recomposition. Also, if a slotid
is not used any more, SubcomposeLayout
will dispose its corresponding composition.
As for where the slotId
goes, that is up to the caller of SubcomposeLayout
. If the content needs it, pass it as a parameter. The above example doesn’t need it as the slotId
is always the same for deferredContent
so it doesn’t need to go anywhere.