본문으로 바로가기

[Android App] Composable Scaffold 에서 SnackBar 사용하기

category Android_app 2023. 4. 10. 17:13

: 아래 내용은 제가 생각한 해석 방법으로 잘못되거나 / 이상한내용은 댓글 부탁드립니다.

   보통은 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 를 처리할수 있습니다.

Snackbar 표시 내용

 

  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>

 

 

그럼 수고하세요.

반응형