안녕하세요! 이번 블로그 포스트에서는 코틀린을 활용하여 안드로이드 앱을 개발하는 방법을 다룰 것입니다. 구체적으로는 개선된 할 일 목록(Todo List) 앱을 만드는 과정을 자세히 설명합니다. 이 앱에는 기본적인 할 일 목록 기능 외에도 데이터베이스와 소셜 공유 기능 등을 추가하여 더욱 유용하게 활용할 수 있도록 개선하였습니다.
강좌 개요
이 강좌는 다음의 주요 항목으로 구성됩니다:
- 프로젝트 설정
- UI 구성
- Room 데이터베이스 설정 및 구현
- 할 일 추가 및 삭제 기능 구현
- 할 일 완료 표시 기능 구현
- 소셜 공유 기능 추가
1. 프로젝트 설정
안드로이드 스튜디오를 통해 새로운 프로젝트를 생성하겠습니다. 프로젝트의 이름은 ‘ImprovedTodoList’로 설정합니다. 이때, 언어는 Kotlin으로 선택하고 최적의 API 레벨을 설정해주세요.
1.1 Gradle 의존성 추가
Room 데이터베이스 및 기타 필요한 라이브러리를 추가해야 합니다. ‘build.gradle (Module: app)’ 파일의 dependencies
섹션에 다음 코드를 추가합니다:
dependencies {
implementation "androidx.room:room-runtime:2.4.2"
kapt "androidx.room:room-compiler:2.4.2"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.1"
implementation "androidx.activity:activity-ktx:1.4.0"
implementation "androidx.appcompat:appcompat:1.4.1"
implementation "com.google.android.material:material:1.5.0"
}
2. UI 구성
먼저 기본적인 UI부터 설계하겠습니다. activity_main.xml
파일에 아래와 같은 코드로 UI를 디자인합니다:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/editTextTodo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="할 일을 입력하세요"/>
<Button
android:id="@+id/buttonAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="추가"/>
<RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
2.1 RecyclerView 및 Adapter 설정
할 일 목록을 보여주기 위해 RecyclerView
를 사용할 것입니다. 아이템의 레이아웃을 정의하는 todo_item.xml
파일을 생성하여 아래와 같은 코드를 추가합니다:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp">
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/textViewTodo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="8dp"
android:paddingEnd="8dp"/>
<Button
android:id="@+id/buttonDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="삭제"/>
</LinearLayout>
3. Room 데이터베이스 설정 및 구현
이제 Room 데이터베이스를 설정하겠습니다. Todo
라는 엔티티 클래스를 생성하여 데이터 테이블의 구조를 정의합니다:
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "todo_table")
data class Todo(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val task: String,
var isCompleted: Boolean = false
)
3.1 TodoDao 인터페이스 생성
Todo 엔티티와 상호작용할 DAO(Data Access Object)를 생성합니다:
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
@Dao
interface TodoDao {
@Insert
suspend fun insert(todo: Todo)
@Query("SELECT * FROM todo_table ORDER BY id ASC")
suspend fun getAllTodos(): List
@Update
suspend fun update(todo: Todo)
}
3.2 RoomDatabase 클래스 생성
Room 데이터베이스를 정의하는 클래스를 생성합니다:
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import android.content.Context
@Database(entities = [Todo::class], version = 1)
abstract class TodoDatabase : RoomDatabase() {
abstract fun todoDao(): TodoDao
companion object {
@Volatile
private var INSTANCE: TodoDatabase? = null
fun getDatabase(context: Context): TodoDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
TodoDatabase::class.java,
"todo_database"
).build()
INSTANCE = instance
instance
}
}
}
}
4. 할 일 추가 및 삭제 기능 구현
MainActivity에서 UI와 Room 데이터베이스를 연결하게 됩니다. 할 일을 추가하는 기능을 구현합니다:
import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private val todoViewModel: TodoViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val adapter = TodoAdapter()
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(this)
todoViewModel.allTodos.observe(this, Observer { todos ->
todos?.let { adapter.submitList(it) }
})
buttonAdd.setOnClickListener {
val task = editTextTodo.text.toString()
if (task.isNotEmpty()) {
todoViewModel.insert(Todo(task = task))
editTextTodo.text.clear()
}
}
}
}
5. 할 일 완료 표시 기능 구현
할 일을 완료로 표시하는 기능을 추가하겠습니다. TodoAdapter
에 체크박스 상태를 반영하는 로직을 추가합니다:
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
class TodoAdapter : ListAdapter(TodoDiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.todo_item, parent, false)
return TodoViewHolder(view)
}
override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
val todo = getItem(position)
holder.bind(todo)
holder.checkBox.setOnCheckedChangeListener { _, isChecked ->
todo.isCompleted = isChecked
// 완료 상태 업데이트
// viewModel.update(todo) // ViewModel에서 update 메서드 호출
}
}
class TodoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textView: TextView = itemView.findViewById(R.id.textViewTodo)
val checkBox: CheckBox = itemView.findViewById(R.id.checkBox)
fun bind(todo: Todo) {
textView.text = todo.task
checkBox.isChecked = todo.isCompleted
}
}
class TodoDiffCallback : DiffUtil.ItemCallback() {
override fun areItemsTheSame(oldItem: Todo, newItem: Todo): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Todo, newItem: Todo): Boolean {
return oldItem == newItem
}
}
}
6. 소셜 공유 기능 추가
마지막으로, 할 일을 소셜 미디어에 공유하는 기능을 추가하겠습니다. Intent
를 사용하여 공유 기능을 구현합니다:
import android.content.Intent
import android.view.View
import androidx.recyclerview.widget.RecyclerView
class TodoAdapter : ListAdapter(TodoDiffCallback()) {
// 이전 코드 생략...
override fun onBindViewHolder(holder: TodoViewHolder, position: Int) {
val todo = getItem(position)
holder.bind(todo)
holder.itemView.setOnClickListener {
val shareIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, todo.task)
type = "text/plain"
}
holder.itemView.context.startActivity(Intent.createChooser(shareIntent, "공유할 곳을 선택하세요."))
}
}
}
결론
이제 개선된 할 일 목록 앱이 완성되었습니다. 이 앱은 이용자가 할 일을 추가하고, 완료 여부를 표시하며, 할 일을 삭제하고, 소셜 미디어에 공유할 수 있는 기능을 제공합니다. 코틀린과 Room 데이터베이스를 활용하여 효율적인 앱을 구축할 수 있었던 이번 강좌가 여러분에게 도움이 되었기를 바랍니다. 다음 포스트에서는 추가적인 기능이나 다른 앱 개발 기술에 대해 다루어보겠습니다. 감사합니다!