Maybe this is a dumb/weird question, but here it g...
# compose
n
Maybe this is a dumb/weird question, but here it goes… I’m facing an issue on Accompanist Navigation Compose Material 0.19.0… I’m not able to use
items
in a
LazyColumn
declared inside of a
bottomSheet
route 😕 No errors, but the bottom sheet is not shown… If I wrap my
LazyColumn
with a
Scaffold
, it works… (but it has some space below the content)… Maybe it’s a measurement issue? 🤔
What I have tried so far: • Just removing
items
from
LazyColumn
and keep static
item
and
stickyHeader
. It works. • Keep the
items
and use a simple
Text
to represent the items… Does not work. • Replace the
LazyColumn
by a simple
Column
. Does not work. • Wrap the
LazyColumn
into a
Scaffold
. It worked with a extra space below the content…
i
cc @jossiwolf
I believe bottom sheets do some custom measurement to determine exactly how tall the bottom sheet actually is (to know if it needs to include a half expanded state). Is your items driven by a Flow you use
collectAsState()
on (i.e., would it be possible that you have no items at all during that first measure pass)?
n
Yep! I just tried with static items and it worked…
Actually… it always has the
stickyHeader
and one
item
as footer, but the items are loaded by the view model and update via `Flow`…
I thought it was working, but the issue is happening when I call the bottom sheet again 😕
w
A few weeks ago I created a custom BottomSheetScaffold to have nested scrollable content; I had to make a few modifications for it to work correctly, but it was not extremely difficult (and was a fun exploration of what kinds of awesomeness the Modifier system was capable of).
the NestedScrollConnection was one of the harder pieces
n
the things are getting more and more weird… I created a separate sample just to file an issue…
Copy code
@Composable
fun BottomSheetViaRoute(
    navBackStackEntry: NavBackStackEntry
) {
    val viewModel: MyViewModel = viewModel(navBackStackEntry)
    val list by viewModel.listFlow.collectAsState(emptyList())
    LaunchedEffect(Unit) {
        viewModel.loadList()
    }
    Column(
        Modifier.verticalScroll(rememberScrollState())
    ) {
        //Text(text = "BottomSheet via route", style = MaterialTheme.typography.h3)
        list.forEach {
            Text(
                text = it,
                Modifier
                    .padding(16.dp)
                    .fillMaxWidth()
            )
        }
    }
}
If I uncomment the
Text
above, the BottomSheet content is not displayed… 😕 The
loadList
above just assign a value to the
listFlow
.
Copy code
fun loadList() {
    _listFlow.value = (0..5).map { 
        "Item $it" 
    }.toList()
}
i
LaunchedEffect
will always start one composition later, so yeah, your list will be empty on that first composition, so you're in the "you have no content at all" state when you leave out the Text which I mentioned above
(that's not specific to Navigation Material, that's more with how bottom sheets work in general...)
n
@Ian Lake not sure if you understood… The bottom sheet is not displayed if I uncomment the
Text
😕 I mean, without the
Text
, it’s working.
w
Are you remembering your height somewhere, and then not recalculating it? It almost sounds to me like the height is getting set in an initial pass, and isn’t updating in subsequent passes. If you change the length of the backing data of your list, does it redraw at its expected new height? If this is what is happening, it would probably be somewhere in your BottomSheetViaRoute class. Interesting problem!
n
I raised a issue with more information… @Ian Lake @jossiwolf https://github.com/google/accompanist/issues/772
😱 If I keep the
Text
only. The code works. If I keep the “list” only. Also works… But not both… 😱
i
You should file a bug against Compose, not Accompanist; none of the positioning is controlled by Accompanist
n
@Ian Lake, but the issue only happens when I put this content in a
bottomSheet
(from accompanist) 😕
(also does not happen in a regular bottom sheet)
i
How are you testing "a regular bottom sheet"? I suspect you're just setting a static sheetContent, which is going to mean your LaunchedEffect already completes before you call show() (as the sheet content is composed even when the sheet isn't visible)
You'd want to have an empty lambda for your sheet content and replace that with your actual content at the same time as you call show() to actually replicate the same flow
w
I found that there was shockingly little magic in the BottomSheet itself. The magic is in the Swipeable modifier and the anchors set on it (as well as the nested scroll connection). Perhaps the behavior you’re looking for can be emulated by building your own?
j
You'll be able to repro this bug against Compose-Material's
ModalBottomSheetLayout
with the scenario Ian described. I filed an issue two weeks ago. We'll try to somehow work around it (we already are trying) but I don't have an immediate great fix for you apart from delaying the first emission of your state by 40-50 ms 😞
n
thanks @jossiwolf. I tried this workaround and it worked in the first navigation. But when I close the bottom sheet and tried to open again, nothing happens 😕 In my simple sample worked, but not in the real app… So I have to investigate more what’s happening… Another workaround which “worked” was put a height for the component like `fillMaxHeight(.7f)`… Anyways, thanks but I’ll postpone updating the project to the next version of the libraries…
j
That's interesting. Thanks for trying - please add any updates to the issue! Sorry about that
👍 2
m
Another workaround which “worked” was put a height for the component like `fillMaxHeight(.7f)`…
Does we need to apply this onto
ModalBottomSheetLayout(modifier = ...)
or which component did you mean? @nglauber
n
No. In the bottom sheet content...
🙏 1
✍️ 1