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

Kazemihabib1996

03/12/2020, 4:57 PM
Please take a look at this function at jetpack compose sample: https://github.com/android/compose-samples/blob/master/JetNews/app/src/main/java/com/example/jetnews/ui/home/HomeScreen.kt#L97
Copy code
@Composable
private fun HomeScreenTopSection(post: Post) {
    ProvideEmphasis(emphasis = EmphasisLevels().high) {
        Text(
            modifier = LayoutPadding(start = 16.dp, top = 16.dp, end = 16.dp, bottom = 0.dp),
            text = "Top stories for you",
            style = MaterialTheme.typography().subtitle1
        )
    }
    Ripple(bounded = true) {
        Clickable(onClick = {
            navigateTo(Screen.Article(post.id))
        }) {
            PostCardTop(post = post)
        }
    }
    HomeScreenDivider()
}
As you see it's an incomplete composable function because we are calling 3 other functions without a Row or Column, and
HomeScreenTopSection
can draw correctly just because the parent has called it inside a column: https://github.com/android/compose-samples/blob/master/JetNews/app/src/main/java/com/example/jetnews/ui/home/HomeScreen.kt#L88
Copy code
Column(modifier = modifier) {
            HomeScreenTopSection(post = postTop)
            HomeScreenSimpleSection(posts = postsSimple)
            HomeScreenPopularSection(posts = postsPopular)
            HomeScreenHistorySection(posts = postsHistory)
        }
So if I call
HomeScreenTopSection
outside a column or row, there are multiple possible solutions: 1) the compose framework can decide to put it inside a Row for example 2) Keep the first one and throw away others and seems that compose follows this approach at the moment. 3) Threw error I think first and second solutions are not appropriate solutions and seems that throwing compile time error is not possible and just remains run time error. Our functions return Unit, if they return something the
HomeScreenTopSection
should return a list and the problem is solved we can throw compile time errors. but with returning functions we loose lots of its benefits so that's not an option here, but what about adding annotations like
ThisShouldBeCalledInsideRowOrColumn
(I know it's a worst naming you ever seen 😬) ?
l

Leland Richardson [G]

03/12/2020, 5:31 PM
this is not a runtime exception because all contexts in which you are able to call a composable are contexts that have a layout policy implied by the parent
as a result, HomeScreenTopSection may have a different behavior if you put it inside of a
Row
vs putting it inside of a
Column
but it is always valid
k

Kazemihabib1996

03/12/2020, 5:40 PM
Yes, but is it valid if I call it outside of Row or Column? and nothing prevents me from doing that.
l

Leland Richardson [G]

03/12/2020, 5:40 PM
if you call it inside of a composable function, a layout policy exists
and that is guaranteed
compose is building a tree
and all nodes in the tree allow an arbitrary number of children
and as such, any composable function can always create any number of nodes in the tree at that location
basically, in terms of the tree that is built, there is no difference between
Copy code
Column {
  Node()
  Node()
  Node()
}
and
Copy code
Column {
  Nodes()
}
Where
Copy code
@Composable fun Nodes() {
  Node()
  Node()
  Node()
}
and both are equally valid
this would be a problem if some nodes in the tree only allowed or expected a single child node, but we have explicitly decided that allowing an arbitrary number of children is a required contract for nodes in the tree
👍 1
k

Kazemihabib1996

03/12/2020, 8:06 PM
Got it, Thanks
3 Views