Thaerith
Thaerith

Reputation: 797

Jetpack-Compose ModalBottomSheetLayout throws java.lang.IllegalArgumentException with initial state "Hidden"

By playing with a ModalBottomSheet in Compose, I get the following issue:

java.lang.IllegalArgumentException: The initial value must have an associated anchor.

My composable function has:

  1. a ModalBottomSheetState and a CoroutinScope,
  2. a ModalBottomSheetLayout with,
  3. a Scaffold as bottom sheet content.
// 1.
val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
val coroutineScope = rememberCoroutineScope()

// 2. 
ModalBottomSheetLayout(
    sheetContent = {
        /* sheetContent */
    },
    sheetState = sheetState,
    // modifier = Modifier.fillMaxSize() --> it doesn't change the result
) {
    // 3.
    Scaffold {
        /* scaffold content */
    }
}

By setting the initial state of the bottom sheet to ModalBottomSheetValue.Expanded, the issue disappears. Note the exception is also thrown for ModalBottomSheetValue.HalfExpanded and without any initial value (the default is Hidden, so it seems logic).

Is there a known workaround or a version of the library where it is working (version of compose I use: 1.0.0 and I tried with 1.0.0-rc2) ?

UPDATE

After some investigation, it seems that the issue is due to a dynamic content in the sheet content. I have there a Column/LazyColumn that recomposes when data are available. By having a fixed content, the issue disappear for any ModalBottomSheetValue.

FIX

With "null" content (understand a content with a height of 0 dp), the composable function has probably not enough information to compose the modal bottom sheet. It is the case with dynamic column content (starting with no content, so height = 0 dp).

To fix this, set a minimal height of 1 dp somewhere in the sheet content hierarchy:

val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
val coroutineScope = rememberCoroutineScope()

ModalBottomSheetLayout(
    sheetContent = {
        Box(modifier.defaultMinSize(minHeight = 1.dp)) {
            /* sheet content */
        }
    },
    sheetState = sheetState,
    // modifier = Modifier.fillMaxSize() --> it doesn't change the result
) {
    Scaffold {
        /* scaffold content */
    }
}

Upvotes: 26

Views: 8614

Answers (4)

Nieto
Nieto

Reputation: 1201

This problem was fixed in version 1.4.0-alpha04

Fixed an issue where ModalBottomSheetLayout would crash if the sheet content was empty. ModalBottomSheetLayout now allows empty sheet content. If the sheet content is empty, it will only have a Hidden state. (Ic2288, b/200980998, b/216693030)

Upvotes: 0

T_Nova
T_Nova

Reputation: 61

For me the approved solution didn't work.

In my case it was failing when I had a bottomSheet content with an unspecified height (lazyColumn) and I wanted the bottomSheet to wrap the height of the content by using this line when opening it:

sheetState.animateTo(ModalBottomSheetValue.HalfExpanded)

For me the solution was to wrap the sheetContent with:

Column(Modifier.fillMaxSize()).

I hope this solution can help someone else out, here is the pseudo code:

    val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
    val coroutineScope = rememberCoroutineScope()
    
    ModalBottomSheetLayout(
        sheetContent = {
            Column(modifier.fillMaxSize()) { ------> The solution
                /* sheet content */
            }
        },
        sheetState = sheetState,
       
    ) {
        Scaffold {
            /* scaffold content */
        }
    }

Upvotes: 2

Mohd Qasim
Mohd Qasim

Reputation: 1020

you can add Spacer in sheetContent to avoid above expecption

sheetContent = {
        Spacer(modifier = Modifier.height(1.dp))
        Box() {
            /* sheet content */
        }
    }

Upvotes: 2

Thaerith
Thaerith

Reputation: 797

With "null" content (understand a content with a height of 0 dp), the composable function has probably not enough information to compose the modal bottom sheet. It is the case with dynamic column content (starting with no content, so height = 0 dp).

To fix this, set a minimal height of 1 dp somewhere in the sheet content hierarchy:

val sheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
val coroutineScope = rememberCoroutineScope()

ModalBottomSheetLayout(
    sheetContent = {
        Box(modifier.defaultMinSize(minHeight = 1.dp)) {
            /* sheet content */
        }
    },
    sheetState = sheetState,
    // modifier = Modifier.fillMaxSize() --> it doesn't change the result
) {
    Scaffold {
        /* scaffold content */
    }
}

Upvotes: 40

Related Questions