- 전체 코드
package com.example.modern_android_2_20230126
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import kotlinx.coroutines.launch
class MainActivity : ComponentActivity() {
@OptIn(ExperimentalComposeUiApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val (text, setValue) = remember {
mutableStateOf("")
}
val scaffoldState = rememberScaffoldState()
val scope = rememberCoroutineScope()
val keyboardController = LocalSoftwareKeyboardController.current
Scaffold(
scaffoldState = scaffoldState
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(it),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
TextField(
value = text,
onValueChange = setValue,
)
Button(onClick = {
keyboardController?.hide()
scope.launch {
scaffoldState.snackbarHostState.showSnackbar("Hello $text")
}
})
{
Text(text = "클릭!!")
}
}
}
}
}
}
- TextField
TextField(
value = "",
onValueChange = {},
)
TextField에 value가 초기에는 빈값이다. 이런 상태면 TextField에 키보드로 어떤 값을 쳐도 아무것도 입력이 안된다. 이것을 동적으로 변하게 할려면 변수같은 형태로 넣어야된다.val text: MutableState<String> = remember {
mutableStateOf("")
}
위와 같이 선언을 해주고 아래와 같이 코드를 적어준다.TextField(
value = text.value,
onValueChange = {
text.value = it,
}
)
입력하면서 변경된 값이 it로 들어가고 it의 값이 text.value로 들어가고 리컴포즈 되면서 value에 값이 들어가게 되는 구조이다.
- 구조분해
val text: MutableState<String> = remember {
mutableStateOf("")
}
위와 같이 적힌 코드에서 MutableState 부분은 아래와같이@Stable
interface MutableState<T> : State<T> {
override var value: T
operator fun component1(): T
operator fun component2(): (T) -> Unit
}
operator라고 되어있는 부분은 구조분해기법을 사용할 수 있다. 그러기에 아래와 같이 코드를 적을 수 있다.val (text, setValue) = remember {
mutableStateOf("")
}
- Scaffold Snackbar, FloatingActionButton 같은 것은 바로 사용이 안되고 Scaffold 안에서 사용이 가능하다. Material의 뼈대와 같은 것이다. Scaffold를 사용하기 위해서는
scaffoldState
를 지정해주어야 된다.val scaffoldState = rememberScaffoldState()
위 코드를 선언해주고Scaffold(
scaffoldState = scaffoldState
) {
...
}
위와 같이 지정해주면 된다.
- 코루틴 스코프 SnackBar는 정적으로 동작하는 Suspend함수이기에 사용하기 위해서는 코루틴 스코프를 활용해야 된다.
val scope = rememberCoroutineScope()
위 코드를 선언 후scope.launch {
scaffoldState.snackbarHostState.showSnackbar("Hello $text")
}
이런식으로 활용하면 된다.