How to properly use Jetpack Compose inside BottomSheetDialogFragment?
C

2

11

For example, I have MyBottomSheetDialogFragment with Compose LazyColumn code in the application:

class MyBottomSheetDialogFragment : BottomSheetDialogFragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return ComposeView(requireContext()).apply {
            setContent {
                Column(horizontalAlignment = Alignment.CenterHorizontally) {
                    Text("Header", color = Color.Black)
                    LazyColumn(
                        Modifier
                            .weight(1f)
                            .fillMaxWidth()) {
                        items(100) {
                            Text("Item $it", Modifier.fillMaxWidth(), Color.Black)
                        }
                    }
                }
            }
        }
    }
}

And show it using this code:

MyBottomSheetDialogFragment().show(activity.supportFragmentManager, null)

That's what we have:

MyBottomSheetDialogFragment screen image.jpg

Now if to scroll LazyColumn list DOWN then everything works as it should, but if to scroll LazyColumn list UP then Bottom Sheet Dialog scrolls instead of LazyColumn list.

How to properly implement LazyColumn inside BottomSheetDialogFragment?

When we used the XML RecyclerView list, to fix this issue we had to wrap the RecyclerView list with NestedScrollView like described here, but how to fix it with Jetpack Compose?

Clincher answered 14/1, 2022 at 12:32 Comment(2)
Any idea? Maybe this question needs some clarification? Or maybe in StackOverflow are already some related answares?Clincher
Same issue, have you found the solution yet? I see that it was improved in alpha 07 of 1.2.0 but I'm not sure if it wasn't fixed for BottomSheetDialogFragment case. See related issue: issuetracker.google.com/issues/174348612Beanstalk
P
1

You can use the new rememberNestedScrollInteropConnection() on compose 1.2.0 which will allow compose to interrupt View's scrolling and enable nested scrolling.

In your case it will be

setContent {

            Column(modifier = Modifier.nestedScroll(rememberNestedScrollInteropConnection()), horizontalAlignment = Alignment.CenterHorizontally) {

                Text("Header", color = Color.Black)

                LazyColumn(
                    Modifier
                        .weight(1f)
                        .fillMaxWidth()) {
                    items(100) {
                        Text("Item $it", Modifier.fillMaxWidth(), Color.Black)
                    }
                }
            }
        }  
Pomology answered 17/8, 2022 at 17:43 Comment(0)
M
0

You should use a BottomSheetScaffold and set the sheetContent with your bottom sheet content. Don't use the BottomSheetDialogFragment.

Here's an example of basic structure of a BottomSheetScaffold:

    val scaffoldState = rememberBottomSheetScaffoldState(
        bottomSheetState = rememberBottomSheetState(BottomSheetValue.Expanded)
    )

    BottomSheetScaffold(
        modifier = Modifier.navigationBarsPadding(),
        scaffoldState = scaffoldState,
        topBar = {
            // Your topBar
        },
        sheetShape = BottomSheetShape,
        sheetPeekHeight = MaterialTheme.spacing.large,
        sheetContent = {
            // Your sheet content
        }
    ) { innerPadding ->
      // You content
    }

Montoya answered 22/2, 2022 at 14:59 Comment(1)
Correct me if I'm wrong but // You content doesn't have to be Composables? For me this API looks like Compose-only with weird structure where BottomSheetScaffold is treated like a parent container for rest of screen. And I think OP wants to interop in a standard way between View and Composables, showing BottomSheetDialogFragment the same way as usual (no need for outer content inside inner lambda, just put a View/Composable where needed). Is it possible to do?Beanstalk

© 2022 - 2024 — McMap. All rights reserved.