android:클래스와리스트를사용하기
클래스와리스트를사용하기
차이
문서의 선택한 두 판 사이의 차이를 보여줍니다.
다음 판 | 이전 판 | ||
android:클래스와리스트를사용하기 [2024/08/08 20:05] – 만듦 이거니맨 | android:클래스와리스트를사용하기 [2024/08/09 00:02] (현재) – [4. 버튼 클릭 이벤트] 이거니맨 | ||
---|---|---|---|
줄 16: | 줄 16: | ||
var id : Int, | var id : Int, | ||
var title : String, | var title : String, | ||
- | var createdAt : LocalDate | + | var createdAt : LocalDateTime |
) | ) | ||
fun getFakeTodo() : List< | fun getFakeTodo() : List< | ||
return listOf< | return listOf< | ||
- | Todo(1, "First todo", | + | Todo(1, "First todo", |
- | Todo(2, " | + | Todo(2, " |
- | Todo(3, "Third todo", | + | Todo(3, "Third todo", |
- | Todo(4, "This is the last todo", | + | Todo(4, "This is the last todo", |
) | ) | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== 화면에 출력하기 ===== | ||
+ | |||
+ | ==== 1. 간단하게 출력해보기 ===== | ||
+ | |||
+ | |||
+ | 위의 제목과 만든 날짜를 화면에 간단하게 출력해보자 | ||
+ | |||
+ | <file kotlin " | ||
+ | package com.dklaw.gogo2.pages | ||
+ | |||
+ | import androidx.compose.foundation.layout.Column | ||
+ | import androidx.compose.foundation.layout.Row | ||
+ | import androidx.compose.foundation.layout.fillMaxHeight | ||
+ | import androidx.compose.foundation.layout.padding | ||
+ | import androidx.compose.foundation.lazy.LazyColumn | ||
+ | import androidx.compose.foundation.lazy.itemsIndexed | ||
+ | import androidx.compose.material3.Text | ||
+ | import androidx.compose.runtime.Composable | ||
+ | import androidx.compose.ui.Modifier | ||
+ | import androidx.compose.ui.unit.dp | ||
+ | import com.dklaw.gogo2.database.Todo | ||
+ | import com.dklaw.gogo2.database.getFakeTodo | ||
+ | import java.time.format.DateTimeFormatter | ||
+ | |||
+ | @Composable | ||
+ | fun ContactsPage() { | ||
+ | |||
+ | val todoList = getFakeTodo() | ||
+ | |||
+ | Column(modifier = Modifier | ||
+ | .fillMaxHeight() | ||
+ | .padding(8.dp)) | ||
+ | { | ||
+ | LazyColumn( | ||
+ | content = { | ||
+ | itemsIndexed(todoList) { | ||
+ | index : Int, item : Todo -> | ||
+ | TodoItem(item = item) | ||
+ | } | ||
+ | } | ||
+ | ) | ||
+ | } | ||
+ | } | ||
+ | |||
+ | @Composable | ||
+ | fun TodoItem(item : Todo) { | ||
+ | val timeFormater : DateTimeFormatter = DateTimeFormatter.ofPattern(" | ||
+ | val nowString = item.createdAt.format(timeFormater) | ||
+ | |||
+ | Row { | ||
+ | Column { | ||
+ | Text(text = nowString) | ||
+ | Text(text = item.title) | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | </ | ||
+ | |||
+ | ===== 데이터 조작하기 ===== | ||
+ | |||
+ | ==== 1. Todo Manager ==== | ||
+ | |||
+ | <file kotlin " | ||
+ | package com.dklaw.gogo2.database | ||
+ | |||
+ | import java.time.LocalDateTime | ||
+ | |||
+ | object TodoManager { | ||
+ | |||
+ | private val todoList = mutableListOf< | ||
+ | |||
+ | fun getAllTodo() : List< | ||
+ | return todoList | ||
+ | } | ||
+ | |||
+ | fun addTodo(title : String) { | ||
+ | todoList.add(Todo(System.currentTimeMillis().toInt(), | ||
+ | } | ||
+ | |||
+ | fun deleteTodo(id : Int) { | ||
+ | todoList.removeIf{ | ||
+ | it.id == id | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | ==== 2. view 모델 ==== | ||
+ | |||
+ | Todo Manager에서 한 데이터 작업을 뷰모델에서 다시 가져온다. | ||
+ | |||
+ | <file kotlin " | ||
+ | package com.dklaw.gogo2.database | ||
+ | |||
+ | import androidx.lifecycle.LiveData | ||
+ | import androidx.lifecycle.MutableLiveData | ||
+ | import androidx.lifecycle.ViewModel | ||
+ | |||
+ | class TodoViewModel: | ||
+ | |||
+ | private var _todoList = MutableLiveData< | ||
+ | val todoList : LiveData< | ||
+ | |||
+ | fun getAllTodo() { | ||
+ | _todoList.value = TodoManager.getAllTodo() | ||
+ | } | ||
+ | |||
+ | fun addTodo(title : String) { | ||
+ | TodoManager.addTodo(title) | ||
+ | getAllTodo() | ||
+ | } | ||
+ | |||
+ | fun deleteTodo(id : Int) { | ||
+ | TodoManager.deleteTodo(id) | ||
+ | getAllTodo() | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== 뷰모델 동기화하기 ===== | ||
+ | |||
+ | ==== 1. 뷰모델을 상속하기 ==== | ||
+ | |||
+ | TodoListPage.kt 에서는 다음과 같이 뷰모델을 상속하여 뷰모델과 동기화할 준비를 한다. | ||
+ | |||
+ | <code kotlin> | ||
+ | @Composable | ||
+ | fun ContactsPage(viewModel: | ||
+ | |||
+ | val todoList by viewModel.todoList.observeAsState() | ||
+ | var inputText by remember { mutableStateOf("" | ||
+ | </ | ||
+ | |||
+ | |||
+ | <WRAP center round tip 90%> | ||
+ | observeAsState()함수를 사용하려면 livedata 디펜던시를 build.gradle.kts(module :app)에 추가해야 한다. | ||
+ | |||
+ | > implementation(" | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== 2. 뷰모델 공급자 지정 ==== | ||
+ | |||
+ | 다음과 같이 mainactivity에 공급자를 지정한다. | ||
+ | |||
+ | <code kotlin> | ||
+ | class MainActivity : ComponentActivity() { | ||
+ | |||
+ | |||
+ | override fun onCreate(savedInstanceState: | ||
+ | super.onCreate(savedInstanceState) | ||
+ | val todoViewModel = ViewModelProvider(this)[TodoViewModel:: | ||
+ | | ||
+ | enableEdgeToEdge() | ||
+ | setContent { | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== 3. 데이터가 없는 경우에 대한 예외 처리 ==== | ||
+ | |||
+ | TodoListPage.kt는 다음과 같이 수정한다. | ||
+ | |||
+ | fakeTodoList()가 아닌 실시간 Todo ViewModel을 사용하는 것이므로 처음에는 데이터 값이 없다. 따라서 이에 대한 예외를 처리해 줘야 한다. | ||
+ | |||
+ | <code kotlin> | ||
+ | todoList? | ||
+ | LazyColumn( | ||
+ | content = { | ||
+ | itemsIndexed(it) { | ||
+ | index : Int, item : Todo -> | ||
+ | TodoItem(item = item) | ||
+ | } | ||
+ | } | ||
+ | ) | ||
+ | }?: Text( | ||
+ | modifier = Modifier.fillMaxWidth(), | ||
+ | textAlign = TextAlign.Center, | ||
+ | text = "No Items yet", | ||
+ | fontSize = 16.sp | ||
+ | ) | ||
+ | </ | ||
+ | |||
+ | ==== 4. 버튼 클릭 이벤트 ==== | ||
+ | |||
+ | === 가. 추가하기 버튼 ==== | ||
+ | |||
+ | TodoListPage.kt에 다음과 같이 버튼 클릭 이벤트를 추가한다. | ||
+ | |||
+ | <code kotlin> | ||
+ | OutlinedTextField(value = inputText, onValueChange = { | ||
+ | inputText = it | ||
+ | }) | ||
+ | Button(onClick = { viewModel.addTodo(inputText); | ||
+ | Text(text = " | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | === 나. 삭제하기 버튼 === | ||
+ | |||
+ | TodoListPage.kt에 다음과 같이 버튼 클릭 이벤트를 추가한다. | ||
+ | |||
+ | <code kotlin> | ||
+ | TodoItem(item = item, onDelete = {viewModel.deleteTodo(item.id)}) | ||
+ | </ | ||
+ | |||
+ | 위와 같이 onDelete라는 대리자를 지정했으므로 다음과 같이 TodoItem함수를 바꿔준다. | ||
+ | |||
+ | <code kotlin> | ||
+ | fun TodoItem(item : Todo, onDelete : ()-> Unit) { | ||
+ | |||
+ | (중략) | ||
+ | |||
+ | IconButton(onClick = onDelete ) { | ||
+ | (후략) | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== 다. 전체 코드 ==== | ||
+ | |||
+ | TodoListPage.kt의 전체 코드는 다음과 같다. | ||
+ | |||
+ | <file kotlin " | ||
+ | package com.dklaw.gogo2.pages | ||
+ | |||
+ | import androidx.compose.foundation.background | ||
+ | import androidx.compose.foundation.layout.Arrangement | ||
+ | import androidx.compose.foundation.layout.Column | ||
+ | import androidx.compose.foundation.layout.Row | ||
+ | import androidx.compose.foundation.layout.Spacer | ||
+ | import androidx.compose.foundation.layout.fillMaxHeight | ||
+ | import androidx.compose.foundation.layout.fillMaxWidth | ||
+ | import androidx.compose.foundation.layout.height | ||
+ | import androidx.compose.foundation.layout.padding | ||
+ | import androidx.compose.foundation.lazy.LazyColumn | ||
+ | import androidx.compose.foundation.lazy.itemsIndexed | ||
+ | import androidx.compose.foundation.shape.RoundedCornerShape | ||
+ | import androidx.compose.material3.Button | ||
+ | import androidx.compose.material3.Icon | ||
+ | import androidx.compose.material3.IconButton | ||
+ | import androidx.compose.material3.MaterialTheme | ||
+ | import androidx.compose.material3.OutlinedTextField | ||
+ | import androidx.compose.material3.Text | ||
+ | import androidx.compose.runtime.Composable | ||
+ | import androidx.compose.runtime.getValue | ||
+ | import androidx.compose.runtime.livedata.observeAsState | ||
+ | import androidx.compose.runtime.mutableStateOf | ||
+ | import androidx.compose.runtime.remember | ||
+ | import androidx.compose.runtime.setValue | ||
+ | import androidx.compose.ui.Alignment | ||
+ | import androidx.compose.ui.Modifier | ||
+ | import androidx.compose.ui.draw.clip | ||
+ | import androidx.compose.ui.graphics.Color | ||
+ | import androidx.compose.ui.res.painterResource | ||
+ | import androidx.compose.ui.text.style.TextAlign | ||
+ | import androidx.compose.ui.unit.dp | ||
+ | import androidx.compose.ui.unit.sp | ||
+ | import com.dklaw.gogo2.R | ||
+ | import com.dklaw.gogo2.database.Todo | ||
+ | import com.dklaw.gogo2.database.TodoViewModel | ||
+ | import java.time.format.DateTimeFormatter | ||
+ | |||
+ | @Composable | ||
+ | fun ContactsPage(viewModel: | ||
+ | |||
+ | val todoList by viewModel.todoList.observeAsState() | ||
+ | var inputText by remember { mutableStateOf("" | ||
+ | |||
+ | |||
+ | |||
+ | Column(modifier = Modifier | ||
+ | .fillMaxHeight() | ||
+ | .padding(8.dp), | ||
+ | { | ||
+ | Spacer(modifier = Modifier.height(32.dp)) | ||
+ | Text(text = " | ||
+ | |||
+ | Row (modifier = Modifier | ||
+ | .fillMaxWidth() | ||
+ | .padding(8.dp), | ||
+ | OutlinedTextField(value = inputText, onValueChange = { | ||
+ | inputText = it | ||
+ | }) | ||
+ | Button(onClick = { viewModel.addTodo(inputText) }) { | ||
+ | Text(text = " | ||
+ | inputText = "" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | todoList? | ||
+ | LazyColumn( | ||
+ | content = { | ||
+ | itemsIndexed(it) { | ||
+ | index : Int, item : Todo -> | ||
+ | TodoItem(item = item, onDelete = {viewModel.deleteTodo(item.id)}) | ||
+ | } | ||
+ | } | ||
+ | ) | ||
+ | }?: Text( | ||
+ | modifier = Modifier.fillMaxWidth(), | ||
+ | textAlign = TextAlign.Center, | ||
+ | text = "No Items yet", | ||
+ | fontSize = 16.sp | ||
+ | ) | ||
+ | |||
+ | } | ||
+ | } | ||
+ | |||
+ | @Composable | ||
+ | fun TodoItem(item : Todo, onDelete : ()-> Unit) { | ||
+ | val timeFormater : DateTimeFormatter = DateTimeFormatter.ofPattern(" | ||
+ | val nowString = item.createdAt.format(timeFormater) | ||
+ | |||
+ | Row (modifier = Modifier | ||
+ | .fillMaxWidth() | ||
+ | .padding(8.dp) | ||
+ | .clip(RoundedCornerShape(16.dp)) | ||
+ | .background(MaterialTheme.colorScheme.primary) | ||
+ | .padding(16.dp), | ||
+ | verticalAlignment = Alignment.CenterVertically | ||
+ | ) { | ||
+ | Column (modifier = Modifier.weight(1f)){ | ||
+ | Text(text = nowString, fontSize = 10.sp, color = Color.LightGray) | ||
+ | Text(text = item.title, fontSize = 20.sp, color = Color.White) | ||
+ | } | ||
+ | IconButton(onClick = onDelete ) { | ||
+ | Icon(painter = painterResource(id = R.drawable.baseline_delete_24), | ||
+ | | ||
+ | } | ||
+ | } | ||
} | } | ||
</ | </ |
android/클래스와리스트를사용하기.1723115145.txt.gz · 마지막으로 수정됨: 2024/08/08 20:05 저자 이거니맨