ViewModel 사용 관련 질문
75
投稿した質問数 2
안녕하세요, 비만도 계산기 강의를 수강하면서 코드를 작성하고 말씀하신 내용들을 학습했는데요.
"bmi state를 통해 bmi값이 변경되면 설정한 콜백이 동작하며 결과화면이 recomposition되고, 네비게이션 컨트롤러로 해당 화면으로 이동한다" 라고 이해했는데요,
navController.navigate("result")
가 수행되면
composable(route = Screen.Result.route) {
ResultScreen(
bmi = viewModel.bmi.value,
onBackClick = {
navController.popBackStack()
}
)
}부분이 실행되기 때문에 bmi가 State가 아니고 지역변수여도 원하는 화면이 나올것이라고 생각해서 코드를 변경했는데 실제로 기존과 동일하게 잘 동작하는것을 확인하였습니다.
본 강의에서는 지역변수를 활용해서도 동작이 되지만, UI와 로직을 분리하는 장점이 있으며 ViewModel이 많이 사용되니 사용하신것으로 이해하면 될까요?
아래는 지역변수로 변경한 코드입니다
package com.example.obesitymachine
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import kotlin.math.pow
sealed class Screen(val route: String) {
data object Home : Screen("home")
data object Result: Screen("result")
}
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
val navController = rememberNavController()
var bmi = 0.0
NavHost(navController = navController, startDestination = Screen.Home.route) {
composable(route = Screen.Home.route) {
HomeScreen(
onResultClick = {height, weight ->
bmi = bmiCalculate(height, weight)
navController.navigate(Screen.Result.route)
}
)
}
composable(route = Screen.Result.route) {
ResultScreen(
bmi = bmi,
onBackClick = {
navController.popBackStack()
}
)
}
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HomeScreen(
modifier: Modifier = Modifier,
onResultClick: (height: Double, weight: Double) -> Unit
) {
val (height, setHeight) = rememberSaveable {
mutableStateOf("")
}
val (weight, setWeight) = rememberSaveable {
mutableStateOf("")
}
Scaffold(
topBar = {
TopAppBar(
title = {
Text("비만도 측정기")
}
)
}
) {
Box(
modifier.padding(it)
) {
Column(
modifier
.fillMaxSize()
.padding(8.dp)
) {
OutlinedTextField(
value = height,
onValueChange = setHeight,
label = {
Text("키")
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Number
),
modifier = Modifier.fillMaxWidth()
)
OutlinedTextField(
value = weight,
onValueChange = setWeight,
label = {
Text("몸무게")
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Number
),
modifier = Modifier.fillMaxWidth()
)
Button(
modifier = Modifier.align(Alignment.End),
onClick = {
onResultClick(height.toDouble(), weight.toDouble())
}
) {
Text("결과")
}
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ResultScreen(
bmi: Double,
onBackClick: () -> Unit
) {
val text = when {
bmi > 25 -> "과체중"
bmi > 18.5 -> "정상"
else -> "저체중"
}
val icon = when {
bmi > 25 -> R.drawable.baseline_sentiment_very_dissatisfied_24
bmi > 18.5 -> R.drawable.baseline_sentiment_satisfied_24
else -> R.drawable.baseline_sentiment_dissatisfied_24
}
Scaffold(
topBar = {
TopAppBar(
title = {
Text("비만도 측정기")
},
navigationIcon = {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = null,
modifier = Modifier.clickable(onClick = onBackClick)
)
}
)
}
) {
Box(
modifier = Modifier.padding(it)
) {
Column(
modifier = Modifier
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(text, fontSize = 30.sp)
Spacer(modifier = Modifier.height(50.dp))
Image(
painter = painterResource(id = icon),
contentDescription = null,
modifier = Modifier.size(100.dp),
colorFilter = ColorFilter.tint(
color = Color.Black
)
)
}
}
}
}
fun bmiCalculate(
height: Double, weight: Double
): Double {
return weight / (height / 100).pow(2.0)
}감사합니다!
回答 1
1
화면 회전을 했을 때 Activity는 파괴되고 다시 생성되기 때문에 지역변수가 다 초기화됩니다.
유지해야 하는 상태는 ViewModel에 가지고 있어야 화면 회전에 대응이 가능합니다.
onTabFavorite 콜백 관련 질문
0
60
2
livedata가 왜 필요한 건지 궁금합니다
0
128
3
깃허브에 있는 MemoryTodoRepository 는 룸을 사용하는게 아닌 메모리에 저장, 수정, 삭제 하는건가요?
0
172
1
이젠 아래와 같은 오류가 뜨는데 KSP가 문제 인걸까요?
0
369
2
영상 1분쯤에서 MainActivity에서 viewModel이 저는 안되고 그래들 문제인거 같은데 해결 방법을 모르겠습니다.
0
186
1
전자액자에서 영상과 깃허브의 내용이 달라서 영상을 다보고 깃허브 내용으로 돌려봤는데 권한요청부터가 안됩니다.
0
189
2
Navigation수업에서 string대신 bitmap을 인자로 넘겨주는 방법?
0
177
1
TodoList - 04에서 recentlyDeleteTodo가 null일 경우 처리 방법 문의
0
171
1
나만의 웹 브라우저 03 - UI와 ViewModel 연동 강의에서 질문들이 있습니다.
0
205
2
Scaffold를 사용하면 Content padding parameter it is not used 에러
0
349
1
Material3로 바뀌면서 강의랑 다른 부분이 초반부터 있는데요.
0
221
1
강의에서 사용하는 리소스(이미지 등)을 다운 받을 수 있으면 좋겠어요.
0
248
2
Card Compose에서 elevation 옵션
1
347
1
구글맵 질문입니다
0
233
1
구글맵강의중에서 ..
0
578
7
drawCircle( color = Color.... 부분에서 빨간줄이 ...
0
269
2
val scaffoldState = rememberScaffoldState() 에서 빨간줄이 생기네요
0
524
1
나만의 웹브라우져 02 코드실행시 에뮬레이터에 따라
0
221
1
나만의 웹브라우져 01 코딩 후 실행하면 아래와 같은 오류가 뜨네요
0
3221
2
비만도계산기 로직작성 에서 문제가 발생했어요 ^^
0
338
3
viewModel() 오류 추가질문입니다
0
1118
2
viewModel: MainViewModel = viewModel() 에 오류있습니다
0
537
3
AAR metadata 관련오류발생
0
1437
3
모바일화면에 키보드가 사라지지 않아
0
250
1

