Android(kotlin) - JetPack Compose - snackBar

하동혁 ·2023년 8월 21일
0

Android Jetpack Compose

목록 보기
12/30
post-thumbnail

snackBar

snackBar의 결과를 변수에 받아 처리하기

// 버튼 클릭시 코루틴 스코프 안에서 실행
        Button(onClick = {
            Log.d("snackBar", "snackBar: 스낵바 버튼 클릭")

            corutineScope.launch {
                // snackBar의 결과를 받을 수 있음
                // 이 결과는 스낵바가 닫아졌는지? 스낵바의 버튼이 눌러졌는지?
                val result = snackbarHostState.showSnackbar(
                    "snackBar show!!"
                    ,"확인"
                    , SnackbarDuration.Short // 스낵바 보여주는 시간
                )

                when(result){
                    SnackbarResult.Dismissed -> {
                        Log.d("snackBar", "snackBar: 스낵바 닫아짐")
                    }
                    SnackbarResult.ActionPerformed -> {
                        Log.d("snackBar", "snackBar: 확인 버튼 눌러짐")
                    }
                }
            }
        }) {
            Text(text = "스낵바 버튼")
        }

snackBar의 결과를 .let{ }으로 처리하기

// 버튼 클릭시 코루틴 스코프 안에서 실행
        Button(onClick = {
            Log.d("snackBar", "snackBar: 스낵바 버튼 클릭")

            corutineScope.launch {
                // snackBar의 결과를 받을 수 있음
                // 이 결과는 스낵바가 닫아졌는지? 스낵바의 버튼이 눌러졌는지?
                snackbarHostState.showSnackbar(
                    "snackBar show!!"
                    ,"확인"
                    , SnackbarDuration.Short // 스낵바 보여주는 시간
                ).let {
                    when(it){
                        SnackbarResult.Dismissed -> {
                            Log.d("snackBar", "snackBar: 스낵바 닫아짐")
                        }
                        SnackbarResult.ActionPerformed -> {
                            Log.d("snackBar", "snackBar: 확인 버튼 눌러짐")
                        }
                    }
                }
            }
        }) {
            Text(text = "스낵바 버튼")
        }

실습 코드

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import com.example.dong.ui.theme.MyComposeStudyTheme
import kotlinx.coroutines.launch

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyComposeStudyTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    snackBar()
                }
            }
        }
    }
}

@Composable
fun snackBar(){

    // var currentSnackbarData by mutableStateOf<SnackbarData?>(null)
    // 스낵바호스트를 클릭해 보면 위 와 같은 코드가 있다.
    // currentSnackbarData는 현재 스낵바가 떠 있으면 값이 들어오고 없으면 null이다.
    val snackbarHostState = remember {
        SnackbarHostState()
    }

    val corutineScope = rememberCoroutineScope()

    // 스낵바의 상태에 따라 버튼의 text를 변경하는 메서드이다.
    // SnackbarData에 접근하여 스낵바가 올라와 있는지 아닌지에 따라 text를 변경한다.
    val buttonTitle : (SnackbarData?) -> String = { snackbarData ->
        if(snackbarData != null){
            "스낵바 숨기기"
        } else{
            "스낵바 보여주기"
        }
    }

    val buttonColor : (SnackbarData?) -> Color = { snackbarData ->
        if(snackbarData != null){
            Color.Blue
        } else{
            Color.Red
        }
    }

    Box(
        modifier = Modifier.fillMaxSize()
        , contentAlignment = Alignment.Center
    ){

        // 버튼 클릭시 코루틴 스코프 안에서 실행
        Button(
            colors = ButtonDefaults.buttonColors(
                backgroundColor = buttonColor(snackbarHostState.currentSnackbarData)
                ,contentColor = Color.White
            )
            ,onClick = {
                Log.d("snackBar", "snackBar: 스낵바 버튼 클릭")

                // 스낵바가 이미 올라와 있는데 스낵바를 띄우는 버튼을 또 클릭하면 스낵바를 내린다.
                if(snackbarHostState.currentSnackbarData != null){
                    Log.d("snackBar", "snackBar: 이미 스낵바가 있음")
                    snackbarHostState.currentSnackbarData?.dismiss()
                    return@Button
                }

                corutineScope.launch {
                    // snackBar의 결과를 받을 수 있음
                    // 이 결과는 스낵바가 닫아졌는지? 스낵바의 버튼이 눌러졌는지?
                    snackbarHostState.showSnackbar(
                        "snackBar show!!"
                        ,"확인"
                        , SnackbarDuration.Short // 스낵바 보여주는 시간
                    ).let {
                        when(it){
                            SnackbarResult.Dismissed ->
                                Log.d("snackBar", "snackBar: 스낵바 닫아짐")

                            // 스낵바에 있는 버튼이 눌러졌을 때 로직처리 하는 부분
                            SnackbarResult.ActionPerformed ->
                                Log.d("snackBar", "snackBar: 확인 버튼 눌러짐")

                        }
                    }
                }
        }) {
            Text(buttonTitle(snackbarHostState.currentSnackbarData))
        }

        // 스낵바가 보여지는 부분은 따로 지정해 주어야 함
        SnackbarHost(hostState = snackbarHostState
            , modifier = Modifier.align(Alignment.BottomCenter))
    }
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    MyComposeStudyTheme {
        snackBar()
    }
}

  • 위 예제 코드 주석에 설명 되어 있듯이 스낵바가 나타나 있는 상태에서 스낵바 버튼을 한 번 더 눌러보면 스낵바가 사라지는 것을 확인할 수 있습니다.
  • 코루틴을 사용함으로써 스낵바를 보여주는 비동기 작업을 수행하도록 했습니다.

0개의 댓글