Jetpack Compose

Jetpack Compose 뒤로가기 눌렀을 때 창 나오도록 하기

junjunjun 2023. 7. 15. 16:30
반응형

본 글은 정확하지 않을 수 있습니다. 참고용으로만 봐주시면 감사하겠습니다.

 

Jetpack Compose에서 제공하는 BackHandler 컴포저블을 사용하면 쉽게 뒤로가기 이벤트를 제어할 수 있다.

 

 

BackHandler

두 개의 매개변수를 가지는데,enabled 를 통해 뒤로가기 버튼을 클릭하였을 때 내가 구현한 onBack() 을 사용할지 여부를 결정할 수 있다.내가 구현한 onBack() 을 사용할 경우 enabled = true 로 지정해 주면 된다.

@SuppressWarnings("MissingJvmstatic")
@Composable
public fun BackHandler(enabled: Boolean = true, onBack: () -> Unit) {
    // Safely update the current `onBack` lambda when a new one is provided
    val currentOnBack by rememberUpdatedState(onBack)
    // Remember in Composition a back callback that calls the `onBack` lambda
    val backCallback = remember {
        object : OnBackPressedCallback(enabled) { // 뒤로가기시 발생되는 이벤트 부분
            override fun handleOnBackPressed() {
                currentOnBack()
            }
        }
    }
    // On every successful composition, update the callback with the `enabled` value
    SideEffect {
        backCallback.isEnabled = enabled
    }
    val backDispatcher = checkNotNull(LocalOnBackPressedDispatcherOwner.current) {
        "No OnBackPressedDispatcherOwner was provided via LocalOnBackPressedDispatcherOwner"
    }.onBackPressedDispatcher
    val lifecycleOwner = LocalLifecycleOwner.current
    DisposableEffect(lifecycleOwner, backDispatcher) {
        // Add callback to the backDispatcher
        backDispatcher.addCallback(lifecycleOwner, backCallback)
        // When the effect leaves the Composition, remove the callback
        onDispose {
            backCallback.remove()
        }
    }
}

 

 

구현 코드

@Composable
fun HomeScreen(
    modifier: Modifier = Modifier,
) {

    var showAlertDialog by remember { mutableStateOf(false) } // 팝업 창을 표시할 컴포저블 UI
    
    if (showAlertDialog) { // 뒤로가기 누를 시에만 활성화 됨
        AlertDialog(
            onDismissRequest = { showAlertDialog = false },
            confirmButton = {},  
        )
    }
    
    BackHandler(enabled = true) { // 뒤로가기 활성화
        showAlertDialog = true    // 뒤로가기 클릭시 알림창 보이도록 설정
    }
    
    ...
}

생각보다 간단하게 뒤로가기를 제어할 수 있었다.

 

 

+ 추가적으로 실수했던 부분

어이없는 실수를 해서 뒤로가기 버튼을 눌렀을 때 알림창이 떴다가 바로 사라지는 버그가 존재했었다.

// 문제의 코드
...
    AlertDialog(
        onDismissRequest = { showAlertDialog = false },
        confirmButton = {
            showAlertDialog = false // 확인버튼이라서 모달창 없애도록 구현했는데..
        },  
    )
...

confirmButton 을 확인 버튼을 눌렀을 때 발생하는 이벤트로 알아서 위 코드처럼 구현해 주었다.

(확인 버튼이 자동으로 생기는 줄 알았다..)

 

기능은 맞지만 사용 방법이 다르게 구현되어 발생한 문제였다. 아래와 같이 사용하면 제대로 작동한다.

...
    AlertDialog(
        onDismissRequest = { showAlertDialog = false },
        confirmButton = {
            TextButton(onClick = { showAlertDialog = false }) {
                Text(text = "확인")
            }
        }, 
        // 팝업 창 내용 설정
    )
...
반응형