개발 일지/기타

[Android] BottomSheetScaffold의 BottomSheet가 사용자 입력으로는 숨겨지지 않지만, 프로그래밍적으로는 숨겨질 수 있게 만들기

interfacer_han 2025. 4. 3. 17:22

#1 문제 상황

#1-1 사용자 입력으로 숨겨지지 않게 만들기

val scaffoldState = rememberBottomSheetScaffoldState(
    bottomSheetState = rememberStandardBottomSheetState(
        skipHiddenState = true
    )
)

이러면 된다. 사실 skipHiddenState는 기본값이 true기에 그냥 val scaffoldState = rememberBottomSheetScaffoldState()만 써도 되긴 한다. 본 게시글의 코드는 기록의 의미가 강하므로, 그냥 명시적으로 밝혀 썼다.

 

#1-2 문제점

FilledTonalButton(
    onClick = {
        scope.launch {
            scaffoldState.bottomSheetState.hide()
        }
    }
) {
    Text("숨기기")
}

#1-1의 scaffoldState를 쓰면서 위와 같은 버튼을 만들면, 버튼 클릭 시 런타임 에러가 난다. scaffoldState에서 프로그래머가 명시적으로 hide()하지 말라 했으니 당연하다면 당연하다. 사용자의 터치로 hide()되는 걸 막으면서 동시에 프로그래밍적으로는 hide() 가능케 하려면 어떡해야 할까?

 

#2 문제 해결

#2-1 상황 우회하기

생각보다 간단하게 해결할 수 있었다. 바로, sheetPeekHeight를 0.dp로 만드는 것이다. 이러면, 숨겨지진 않았지만 그렇다고 보이지도 않는 상태가 된다.

 

#2-2 코드 - 구조

...

class MainActivity : ComponentActivity() {
    @OptIn(ExperimentalMaterial3Api::class)
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        setContent {
            val scaffoldState = rememberBottomSheetScaffoldState()
            val scope = rememberCoroutineScope()
            var sheetPeekHeight by remember { mutableStateOf(300.dp) }

            BottomSheetIsNotHideableByUserButProgrammableTheme {
                BottomSheetScaffold(
                    sheetContent = {
                        ...
                    },
                    modifier = ...
                    scaffoldState = scaffoldState,
                    sheetPeekHeight = sheetPeekHeight,
                    topBar = {
                        ...
                    }
                ) { ...
                    ...
                }
            }
        }
    }
}

지역 변수 sheetPeekHeight를 State로 선언하는 게 핵심이다. Recomposition을 유발해야하기 때문이다.

 

#2-3 코드 - sheetPeekHeight 변경

FilledTonalButton(
    onClick = {
        scope.launch {
            sheetPeekHeight = 0.dp
        }
    }
) {
    Text("0.dp")
}

이 버튼을 누르면 BottomSheet가 쨘하고 '사라진다 (#2-1)'. 당연히 런타임 에러 또한 나지 않고 말이다.

 

#4 완성된 앱

#4-1 스크린샷

 

#4-2 전체 소스코드

 

android-practice/playground/BottomSheetIsNotHideableByUserButProgrammable at master · Kanmanemone/android-practice

Contribute to Kanmanemone/android-practice development by creating an account on GitHub.

github.com