1. 목표
- TodoList 제작하기
- Item을 CardView 이용해서 조금 더 깔끔하게 UI 디자인 하기
- Room Database를 이용하여 추가 수정할 수 있도록 만들기.
- 삭제 버튼을 구현하여 언제든지 삭제할 수 있도록 만들기
2. 사용 기술
- RecyclerView
- Room database
- MVVM databinding
3. 제작 구조
이런 구조로 제작하였다. 안드로이드 체계에 맞추어 data와 domain, ui 파트로 나누어 작업하였다.
1편에서는 xml과 Room Database 요소인 Todo와 AppDatabase, TodoDAO에 대해 살펴볼 예정이다.
4. 코드 구성
4-1. build.gradle
plugins {
// Room
id 'kotlin-kapt'
}
dependencies {
// Room Database
implementation 'androidx.room:room-runtime:2.5.0'
kapt 'androidx.room:room-compiler:2.5.0'
kapt 'androidx.room:room-common:2.5.0'
implementation 'androidx.room:room-ktx:2.5.0'
}
어노테이션을 달기 위한 kotlin-kapt 추가와 룸 데이터베이스를 위한 여러가지들 추가한다.
자세한 설명은 아래 공식 링크에 잘 되어 있다.
Room을 사용하여 로컬 데이터베이스에 데이터 저장 | Android 개발자 | Android Developers
Room 라이브러리를 사용하여 더 쉽게 데이터를 유지하는 방법 알아보기
developer.android.com
4-2. xml
1) 구성
- activity_main.xml
- item_recycler.xml
2) activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.MainActivity">
<LinearLayout
android:id="@+id/LL_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_marginBottom="30dp">
<EditText
android:id="@+id/et_todo_input"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/enter_your_to_do_item_here"
android:gravity="center"
android:layout_marginStart="10dp"
android:layout_gravity="center_horizontal"/>
<ImageButton
android:id="@+id/btn_input"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/btn_image"
android:background="?attr/selectableItemBackgroundBorderless"
android:layout_marginEnd="10dp"
android:layout_marginStart="10dp"/>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_todo_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/LL_input"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:layout_marginBottom="10dp"
android:scrollbars="vertical"
tools:listitem="@layout/item_recycler"/>
</RelativeLayout>
3) item_recycler.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_margin="10dp"
app:cardElevation="10dp"
app:cardCornerRadius="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_todo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:ellipsize="end"
android:maxLines="2"
app:layout_constraintBottom_toBottomOf="@id/tv_time"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginBottom="15dp"
android:text='내용'/>
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="기록 시간"
android:layout_marginStart="10dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="5dp"/>
<Button
android:id="@+id/btn_delete"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/baseline_highlight_off_24"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginEnd="10dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</layout>
카드 뷰를 이용하여 둥근 모서리를 가진 보다 깔끔한 디자인의 할 일 목록을 제작하였다.
4-3. Room Database 관련 클래스
1) Room 구조
룸은 3가지 주요 구성요소가 있다.
- 데이터베이스 클래스 : 데이터베이스를 보유하고 앱의 영구 데이터와의 기본 연결을 위한 기본 액세스 포인트 역할을 한다.
- 데이터 항목 : 앱 데이터베이스의 테이블을 나타낸다.
- 데이터 액세스 객체(DAO) : 앱이 데이터베이스의 데이터를 쿼리, 업데이트, 삽입, 삭제하는 데 사용할 수 있는 메서드를 제공한다.
2) Todo - 데이터 항목
package com.example.todolist.domain
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.text.SimpleDateFormat
import java.util.*
// Database table Definition
@Entity(tableName = "todos")
data class Todo(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
var content : String,
var timestamp: String = SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(Date())
)
Room Database는 필요한 데이터 클래스를 Entity로 어노테이션을 달아 정의한다.
id로 생성된 객체를 구분하는데, 여기서 PrimaryKey(autoGenerate = true)는 구분하는 id를 자동적으로 생성하여 1씩 증가하게 만들으라는 이야기이다.
즉, 각 객체에 고유한 id를 만들어 준다고 생각하면 편하다.
3) TodoDAO - 데이터 액세스 객체(DAO)
package com.example.todolist.data
import androidx.lifecycle.LiveData
import androidx.room.*
import com.example.todolist.domain.Todo
// Data Access Objects
@Dao
interface TodoDAO {
@Query("SELECT * FROM todos")
fun getAll(): LiveData<List<Todo>>
@Query("SELECT * FROM todos WHERE content = :content")
fun getTodoByContent(content: String): Todo?
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(todo: Todo)
@Update
fun update(todo: Todo)
@Delete
fun delete(todo: Todo)
@Query("DELETE FROM todos WHERE content = :content")
fun deleteByContent(content: String)
}
테이블의 데이터와 상호작용하는 데 사용하는 메서드를 제공한다.
4) AppDatabase - 데이터베이스 클래스
package com.example.todolist.data
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import com.example.todolist.domain.Todo
// Database Class Definitions
@Database(entities = [Todo::class], version = 2)
abstract class AppDatabase : RoomDatabase() {
// Create DAO Object
abstract fun todoDAO(): TodoDAO
// Singleton instance
companion object {
private var instance: AppDatabase? = null
// make instance
fun getInstance(context: Context): AppDatabase? {
if (instance == null)
synchronized(AppDatabase::class){
instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"Todo.db"
)
.build()
}
return instance
}
}
}
싱글톤 인스턴스를 제작하여 반환한다.
이것으로 대략적인 xml UI 디자인과 Room Database를 이용한 코드 구성을 마무리 하였다.
다음에는 MVVM을 이용하여 유기적으로 구성하는 것을 설명할 예정이다.
전체 코드를 보고 싶다면 아래 링크를 참조하길 바란다.
GitHub - geonunggoodboy/ToDoList
Contribute to geonunggoodboy/ToDoList development by creating an account on GitHub.
github.com
'Kotlin > 개인 프로젝트' 카테고리의 다른 글
날씨 앱 제작: 전체적인 작동 구조 고안 (0) | 2023.03.08 |
---|---|
날씨 정보 앱 제작 : 사전 연습 (0) | 2023.02.27 |
개인 프로젝트 : 코틀린으로 To-do List - MVVM 사용하기 (0) | 2023.02.19 |