[Android App] Composable Scaffold 에서 SnackBar 사용하기
: 아래 내용은 제가 생각한 해석 방법으로 잘못되거나 / 이상한내용은 댓글 부탁드립니다.
보통은 Scaffold 를 먼저 설명하고 SnackBar 를 사용하는데 거꾸로 한번 해봤습니다.
1> Snackbar 함수의 다큐먼트 찾기
→ Snackbar() 입력후 Ctrl +B 를 눌러줍니다.
▶ SnackBar.kt 파일에 존재하는 함수이고 아래와 같은 부분이 있네요.
→ 디폴트 인자와 함께 Snackbar 를 사용할려면
ScaffoldState.snackbarHostState 와 SnackbarHostState.showSnackbar 를 사용하라고 하네요.
▶ ScaffoldState 변수 만들기
→ ScaffldState 정의는 Scaffold.kt 파일 안에 클래스로 정의되어 있습니다. (
→ 디폴트 값 사용한 변수 생성은 rememberScaffoldState() 함수를 사용합니다.
val scaffoldState:ScaffoldState = rememberScaffoldState()
→ rememberScaffoldState() 함수 정의의 SnackbarHostState 관련 파라미터 정보를 읽어 보겠습니다.
→ Scaffold 안에서서 사용하라고 적혀 있네요.
▶ 위내용 적용해 Composable 함수를 간단히 만들어 봤습니다.
@Composable
fun SnackbarDemo(_scaffoldState:ScaffoldState) {
// Scaffold() 를 사용하라고 해서 추가했고 인자중 scaffoldState 변수도 설정을 했습니다.
Scaffold(scaffoldState = _scaffoldState) {
Button() {
Text("click me")
}
}
}
▶ ScaffoldState.snackbarHostState 와 SnackbarHostState.showSnackbar 를 적용한 코드
아래코드를 Button의 onClick() 안에 추가해 봤습니다.
_scaffoldState.snackbarHostState.showSnackbar("Hello")
fun SnackbarDemo(_scaffoldState:ScaffoldState) {
Scaffold(scaffoldState = _scaffoldState) {
Button(onClick = {
_scaffoldState.snackbarHostState.showSnackbar("Hello") <-- 요기
}) {
Text("click me")
}
}
}
→ 좌측에 아이콘이 하나 생기고 에러가 발생하네요
: 좌측 아이콘의 의미는 suspend 함수라는 뜻이고, showSnackbar 로 마우스를 이동하니 아래처럼
Suspend 함수는 coroutine 또는 다른 suspend 함수안에서 호출되야 한다고 적혀 있습니다.
▶ Coroutine 변수 만들기
→ 안드로이드 개발자 사이트 링크
→ 위 사이트참조해 Coroutine 을 만들어 봤습니다.
fun SnackbarDemo(_scaffoldState:ScaffoldState) {
val scope = rememberCoroutineScope() <-- 추가된 부분
Scaffold(scaffoldState = _scaffoldState) {
Button(onClick = {
scope.launch { <-- 추가된 부분
_scaffoldState.snackbarHostState.showSnackbar("Hello")
} <-- 추가된 부분
}) {
Text("click me")
}
}
}
▶ 동작 영상 첨부
< 정리>
: Scaffold 레이아웃에서 Snackbar를 표시하기위해 필요한 사항
→ Scaffold() 레이아웃 안 ScaffoldState 선언 및 사용방법
val scaffoldState:ScaffoldState = rememberScaffoldState()
Scaffold(scaffoldState = scaffoldState) {
~~ 중략 ~~
}
→ Coroutine 을 이용한 Snackbar 화면 표시법
val scope = rememberCoroutineScope()
scope.launch {
scaffoldState.snackbarHostState.showSnackbar("Hello")
}
< 주의사항>
→ showSnackbar() 는 suspend 함수로 coroutine에서 실행되야 합니다.
<기타>
▶ Button 경고창 제거하기
함수 이름 앞에 아래의 어노테이션을 추가해 줍니다.
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
▶ showSnackbar() 리턴값 처리하기 (ActionPerformed , Dismissed)
: 리턴 타입은 SnackbarResult 이고 actionLabel 에 문자열을 넣어야 ActionPerformed 를 처리할수 있습니다.
Coroutine 코드는 아래와 같습니다.
scope.launch {
val snackbarResult=scaffoldState.snackbarHostState.showSnackbar(
"Hello ",
actionLabel = "Undo",
duration = SnackbarDuration.Short,
)
when(snackbarResult){
SnackbarResult.ActionPerformed -> Log.d("SnackBar","actionPerformed") <-- Undo 클릭시
SnackbarResult.Dismissed -> Log.d("SnackBar","dismissed") <-- timeout으로 사라질 경우
}
}
▶ TextField() 사용시 Snackbar 가 키보드 뒤에 숨는 문제
AndroidManifest.xml 파일
<activity
~~ 중략 ~~
android:windowSoftInputMode="adjustResize"
</activity>
그럼 수고하세요.