일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Compose
- ListAdapter
- 플레이스토어
- MVVM
- Jetpack
- 커스텀뷰
- 클린아키텍처
- UiState
- sharedFlow
- Authentication
- 안드로이드
- 코틀린
- 회원가입
- Android
- NavController
- coroutine
- DiffUtil
- Build variants
- cleanarchitecture
- 파이어베이스
- Kotlin
- NavHost
- Flow
- 알고리즘
- 컴포즈
- 리사이클러뷰
- 로그인
- XML
- 뷰
- 코딩테스트
- Today
- Total
Grusie 안드로이드 개발 기술 블로그
[Android] 안드로이드 컴포즈 Snackbar 사용하기 본문
메세지를 띄우는 방법은 여러 가지가 있다. 토스트로 띄우는 방법, 다이얼로그로 띄우는 방법 등 여러가지가 있겠지만, 이번에는 SnackBar를 활용해서 띄워보도록 하자.
SnackBar는 하단에 간단한 메세지를 표현하는데에 사용되는 메세지로, 화면에 국한되어 있다고 생각하는 게 편하다.
Toast와 다르게 콜백을 받아 처리할 수 있으며, 간단한 Action을 구현하는 것도 가능하다.
기본 사용법
val snackBarHostState = remember { SnackbarHostState() }
val coroutine = rememberCoroutineScope()
스낵바를 사용하기 위해선, 스낵바의 상태를 확인 할 수 있는 SnackbarHostState가 필요하다.
coroutine.launch {
snackBarHostState.showSnackbar(
message = TextUtils.getErrorMsg(
context,
error = errorCode!!
)
)
또한 스낵바의 showSnackbar는 suspend 함수이기 때문에, 코루틴에서 실행되어야 한다.
콜백 받기
if (errorCode != null) {
coroutine.launch {
val result = snackBarHostState.showSnackbar(
message = TextUtils.getErrorMsg(
context,
error = errorCode!!
)
)
when (result) {
SnackbarResult.Dismissed -> {
//닫힐 경우
errorCode = null
}
SnackbarResult.ActionPerformed -> {
//액션에 대한 처리
}
}
}
}
SnackBarHostState의 showSnackbar는 정지함수이면서, SnackbarResult를 리턴해주는 함수이다.
그렇기에 사용 할 때의 결과값을 반환 받아, Dismissed일 때 상태를 변경해주는 코드를 작성했다.
/**
* Possible results of the [SnackbarHostState.showSnackbar] call
*/
enum class SnackbarResult {
/**
* [Snackbar] that is shown has been dismissed either by timeout of by user
*/
Dismissed,
/**
* Action on the [Snackbar] has been clicked before the time out passed
*/
ActionPerformed,
}
SnackbarResult는 이렇게 생겼다.
액션 넣기
suspend fun showSnackbar(
message: String,
actionLabel: String? = null,
withDismissAction: Boolean = false,
duration: SnackbarDuration =
if (actionLabel == null) SnackbarDuration.Short else SnackbarDuration.Indefinite
): SnackbarResult =
showSnackbar(SnackbarVisualsImpl(message, actionLabel, withDismissAction, duration))
showSnackbar의 구조를 보면 이런식으로 생겼다.
액션을 넣기 위해서는 actionLabel에 String값을 넣으면 된다.
if (errorCode != null) {
coroutine.launch {
val result = snackBarHostState.showSnackbar(
message = TextUtils.getErrorMsg(
context,
error = errorCode!!
),
actionLabel = "닫기"
)
when (result) {
SnackbarResult.Dismissed -> {
errorCode = null
}
SnackbarResult.ActionPerformed -> {
errorCode = null
}
}
}
}
닫기라는 액션 라벨을 넣고, 클릭 시 닫히도록 구현하였다.
Scaffold와 함께 사용
Scaffold와 함께 사용할 때에는 따로 처리해주어야 하는 것이 있는 것 같다.
이전 버전에서는 scaffoldState를 생성하여, 거기에서 Snackbar를 사용해야 하는 것 같으나, 필자가 사용하는 마테리얼3(1.6.2) 에서는 snackbarHost를 넣는 곳이 따로 있었다.
Scaffold(
modifier = modifier,
...
snackbarHost = { SnackbarHost(hostState = snackBarHostState) }
...
)
snackbarHost에 hostState를 파라미터로 가지는 SnackBarHost를 생성해 넣어주면 된다.
실제 동작 화면
후기
토스트메세지에 비해서 익숙하지 않아 어렵다고 생각했으나, 오히려 Dialog를 띄우는 것 보다 간단하고, Action으로 기능도 쉽게 넣을 수 있는 것 같아 애용 해야겠다고 생각한다. 특히 SnackBar가 디자인이 예뻐서 다이얼로그를 띄우는 것 보다 나은 것 같다. 추가로 토스트메세지에 비해, 화면에 종속되어 있어, 화면을 벗어났을 때 남아있지 않기에 사용자에게 좋은 경험을 줄 수 있을 것이라고 생각한다.
아쉬운 점이 있다면, 키보드가 띄워져있을 때에는 가려진다는 점이다. 그래서 SnackBar를 띄울 때 키보드를 강제로 닫는식으로 처리해야 할 것 같다.
'안드로이드 개발 > 컴포즈' 카테고리의 다른 글
[Android] 컴포즈 사이드 이펙트 - SideEffect, LaunchedEffect, DisposableEffect (1) | 2024.03.18 |
---|