Android Compose에서 여러 하단 시트를 사용하는 방법

내 프로젝트를 일반 뷰 시스템에서 Android Compose로 리팩토링한 후, 그 차이를 정말 느낄 수 있었습니다.

Android Compose가 기본 Android에서 UI를 빌드하는 기본 방법이 될 것이라고 생각하지만 여전히 Google 엔지니어가 해결하려고 하는 많은 단점이 있지만 그때까지 이 중 하나를 해결하는 방법에 대해 작성하겠습니다. 게시물이며 동일한 앱에서 여러 하단 시트를 갖는 방법입니다.

이 기사를 읽은 후 아래와 같이 여러 하단 시트를 쉽게 만들 수 있습니다.


먼저 읽기 전에 이 게시물이 Compose 버전1.0.0-beta05에 적용된다는 점에 유의하십시오.
다음과 같은 문제와 확실히 관련이 있습니다.
  • Integration Bottom sheets with navigation
  • composable dialog

  • 이 두 가지 문제가 아직 해결되지 않은 경우 내 게시물을 계속 읽을 수 있으며, 그 중 하나라도 해결되고 여러 바텀 시트를 지원하는 방식이 변경되면 다른 게시물을 작성하겠습니다.

    1- 이제 응용 프로그램에서 사용할 하단 시트를 정의하여 시작하겠습니다.

    sealed class BottomSheetScreen() {
        object Screen1: BottomSheetScreen()
        object Screen2: BottomSheetScreen()
        class Screen3(val argument:String):BottomSheetScreen()
    }
    


    2- 현재 시트의 변경 가능한 상태를 갖게 됩니다.

    @Composable
    private fun MainLayout() {
      var currentBottomSheet: BottomSheetScreen? by remember{
            mutableStateOf(null)
        }
    }
    


    3- BottomSheetScaffold를 사용하여 하단 시트 열기 및 닫기를 처리합니다.

       val scaffoldState = rememberBottomSheetScaffoldState()
       BottomSheetScaffold(sheetPeekHeight = 0.dp, scaffoldState = scaffoldState,
            sheetShape = BottomSheetShape,
            sheetContent = {
               currentBottomSheet?.let { currentSheet ->
                    SheetLayout(currentSheet,closeSheet)
                }
            }) { paddingValues ->
                Box(Modifier.padding(paddingValues)){
                    MainContent(openSheet)
                }
        }
    


    4- 이제 하단 시트를 열고 닫는 두 개의 람다를 정의합니다.

    val closeSheet: () -> Unit = {
            scope.launch {
                scaffoldState.bottomSheetState.collapse()
    
            }
        }
    
    
        val openSheet: (BottomSheetScreen) -> Unit = {
            currentBottomSheet = it
            scope.launch { scaffoldState.bottomSheetState.expand() }
    
        }
        // to set the current sheet to null when the bottom sheet closes
        if(scaffoldState.bottomSheetState.isCollapsed)
            currentBottomSheet = null
    


    요약하면 코드는 다음과 유사해야 합니다.

    @OptIn(ExperimentalMaterialApi::class)
    @Composable
    private fun MainLayout() {
        val scope = rememberCoroutineScope()
        val scaffoldState = rememberBottomSheetScaffoldState()
        var currentBottomSheet: BottomSheetScreen? by remember{
            mutableStateOf(null)
        }
    
        val closeSheet: () -> Unit = {
            scope.launch {
                scaffoldState.bottomSheetState.collapse()
            }
        }
    
    
        val openSheet: (BottomSheetScreen) -> Unit = {
            currentBottomSheet = it
            scope.launch { scaffoldState.bottomSheetState.expand() }
    
        }
      if(scaffoldState.bottomSheetState.isCollapsed)
            currentBottomSheet = null
    
        BottomSheetScaffold(sheetPeekHeight = 0.dp, scaffoldState = scaffoldState,
            sheetShape = BottomSheetShape,
            sheetContent = {
              currentBottomSheet?.let { currentSheet ->
                    SheetLayout(currentSheet,closeSheet)
                }
            }) { paddingValues ->
                Box(Modifier.padding(paddingValues)){
                    MainContent(openSheet)
                }
        }
    }
    


    5- 이제 우리는 SheetLayout 를 정의할 것입니다. 위의 코드에서 두 개의 매개변수를 취하는 것을 볼 수 있습니다.
  • 현재 하단 시트
  • closeSheet 람다, 시트를 닫는 버튼을 원할 경우

  • 그거랑 비슷해야

    @Composable
    fun SheetLayout(currentScreen: BottomSheetScreen,onCloseBottomSheet :()->Unit) {
        BottomSheetWithCloseDialog(onCloseBottomSheet){
            when(currentScreen){
                BottomSheetScreen.Screen1 -> Screen1()
                BottomSheetScreen.Screen2 -> Screen2()
                is BottomSheetScreen.Screen3 -> Screen3(argument = currentScreen.argument)
            }
    
        }
    }
    


    6- 마지막으로 MainContent를 매개변수로 취하는 구성 가능한 함수openSheet를 정의하는 마지막 단계

    @Composable
    fun MainContent(openSheet: (BottomSheetScreen) -> Unit) {
        Column(Modifier.fillMaxSize(),verticalArrangement = Arrangement.SpaceEvenly,horizontalAlignment = Alignment.CenterHorizontally) {
            Text(text = "This is Main Content")
            Button(onClick = { openSheet(BottomSheetScreen.Screen1) }) {
                Text(text = "Open bottom sheet 1")
            }
    
            Button(onClick = { openSheet(BottomSheetScreen.Screen2) }) {
                Text(text = "Open bottom sheet 2")
            }
            Button(onClick = { openSheet(BottomSheetScreen.Screen3("this is an argument")) }) {
                Text(text = "Open bottom sheet 2")
            }
        }
    }
    
    


    NB: 다음은 데모에서 사용된 전체 프로젝트입니다Github.

    읽어주셔서 감사합니다 🐱‍🏍

    좋은 웹페이지 즐겨찾기