Hello! This time, as part of a series of lectures on Android app development using Kotlin, we will create a task management application. This application will provide users with the ability to manage their to-do list and will help in learning basic CRUD (Create, Read, Update, Delete) operations.
1. Project Setup
First, we need to set up a new Android project. Open Android Studio and follow these steps:
- Click on New Project.
- Select Empty Activity and click Next.
- Enter ‘TaskManager’ in Project Name and set Language to Kotlin.
- Finally, click on Finish.
2. Define Data Model
Define a data model class called Task
that represents a task. This class will have properties for the task’s title, description, and completion status:
data class Task(
var id: Long = 0,
var title: String,
var description: String,
var isCompleted: Boolean = false
)
3. Design User Interface
The basic user interface of the task management application consists of the following elements:
- A RecyclerView that displays the list of tasks
- A button to add a new task
- Options to edit and delete tasks
First, we modify the activity_main.xml
file to set up the user interface:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_add_task"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add New Task"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
4. Setup RecyclerView
We display the list of tasks using RecyclerView. Next, we create a TaskAdapter
class to show the task items in a list format:
class TaskAdapter(private val tasks: List) : RecyclerView.Adapter() {
inner class TaskViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val taskTitle: TextView = itemView.findViewById(R.id.task_title)
val taskDescription: TextView = itemView.findViewById(R.id.task_description)
val taskStatus: CheckBox = itemView.findViewById(R.id.task_status)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.task_item, parent, false)
return TaskViewHolder(view)
}
override fun onBindViewHolder(holder: TaskViewHolder, position: Int) {
val task = tasks[position]
holder.taskTitle.text = task.title
holder.taskDescription.text = task.description
holder.taskStatus.isChecked = task.isCompleted
holder.taskStatus.setOnCheckedChangeListener { _, isChecked ->
task.isCompleted = isChecked
}
}
override fun getItemCount(): Int {
return tasks.size
}
}
4.1. Create task_item.xml Layout
Create the task_item.xml
file for each item in the RecyclerView as follows:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/task_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"/>
<TextView
android:id="@+id/task_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"/>
<CheckBox
android:id="@+id/task_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
5. Implement Add and Delete Task Features
We will implement the functionality to add new tasks and delete existing ones. Add the following code in MainActivity
:
class MainActivity : AppCompatActivity() {
private val taskList = mutableListOf()
private lateinit var taskAdapter: TaskAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
taskAdapter = TaskAdapter(taskList)
findViewById(R.id.recycler_view).apply {
layoutManager = LinearLayoutManager(this@MainActivity)
adapter = taskAdapter
}
findViewById
5.1. Create Task Add Dialog Layout
Create the dialog_add_task.xml
file with the following content:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/task_title_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Task Title"/>
<EditText
android:id="@+id/task_description_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Task Description"/>
</LinearLayout>
6. Manage Data Storage
We will use the Room database to maintain the task list even after the app is restarted. Using Room allows us to easily store and manage objects in an SQLite database. We will proceed with the setup for this process:
- Add Room dependencies to the Gradle file:
dependencies {
implementation "androidx.room:room-runtime:2.4.1"
kapt "androidx.room:room-compiler:2.4.1"
}
6.1. Define Room Entity
We define an entity for the Room database using a new TaskEntity
class:
@Entity(tableName = "tasks")
data class TaskEntity(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
val title: String,
val description: String,
val isCompleted: Boolean = false
)
6.2. Define DAO Interface
We define a Data Access Object (DAO) interface to interact with the Room database:
@Dao
interface TaskDao {
@Insert
suspend fun insert(task: TaskEntity)
@Query("SELECT * FROM tasks")
suspend fun getAllTasks(): List
@Delete
suspend fun delete(task: TaskEntity)
}
6.3. Define Database Class
We define a database class that inherits from Room Database:
@Database(entities = [TaskEntity::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun taskDao(): TaskDao
}
6.4. Initialize Database
Add logic to the main activity to initialize the database and load tasks:
private lateinit var db: AppDatabase
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = Room.databaseBuilder(applicationContext, AppDatabase::class.java, "task-database").build()
// Load tasks
loadTasks()
}
private fun loadTasks() {
CoroutineScope(Dispatchers.IO).launch {
val tasks = db.taskDao().getAllTasks()
taskList.clear()
taskList.addAll(tasks.map { Task(it.id, it.title, it.description, it.isCompleted) })
runOnUiThread { taskAdapter.notifyDataSetChanged() }
}
}
7. Implement Task Deletion Feature
We implement functionality that allows users to delete tasks. Add the following code:
override fun onBindViewHolder(holder: TaskViewHolder, position: Int) {
// Maintain existing code
holder.itemView.setOnLongClickListener {
deleteTask(task)
true
}
}
private fun deleteTask(task: Task) {
CoroutineScope(Dispatchers.IO).launch {
db.taskDao().delete(TaskEntity(task.id, task.title, task.description, task.isCompleted))
runOnUiThread {
taskList.remove(task)
taskAdapter.notifyDataSetChanged()
}
}
}
8. Conclusion and Additional Improvements
With this, the basic structure and functionality of your task management application are complete! This application provides users with the ability to add, edit, and delete tasks from their list. You might consider several additional improvements, including:
- Adding a feature to display the date when a task was completed
- Adding the ability to set task priorities
- Adding search and filter functionality for tasks
- Improving design for better UI/UX
Creating your own task management application using Kotlin and Android Studio will be a great learning experience. I hope this tutorial has been helpful. If you have any questions or need additional information, please leave a comment!