Cookie Consent by Free Privacy Policy Generator 📌 Android Jetpack Compose - Creating A Simple Todo

🏠 Team IT Security News

TSecurity.de ist eine Online-Plattform, die sich auf die Bereitstellung von Informationen,alle 15 Minuten neuste Nachrichten, Bildungsressourcen und Dienstleistungen rund um das Thema IT-Sicherheit spezialisiert hat.
Ob es sich um aktuelle Nachrichten, Fachartikel, Blogbeiträge, Webinare, Tutorials, oder Tipps & Tricks handelt, TSecurity.de bietet seinen Nutzern einen umfassenden Überblick über die wichtigsten Aspekte der IT-Sicherheit in einer sich ständig verändernden digitalen Welt.

16.12.2023 - TIP: Wer den Cookie Consent Banner akzeptiert, kann z.B. von Englisch nach Deutsch übersetzen, erst Englisch auswählen dann wieder Deutsch!

Google Android Playstore Download Button für Team IT Security



📚 Android Jetpack Compose - Creating A Simple Todo


💡 Newskategorie: Programmierung
🔗 Quelle: dev.to

Introduction

Hello! 😎
In this tutorial I will show you how to create a simple Todo application using Android Jetpack Compose and using Jetpack's Room library.

Creating The Project

First we need to actually create the project, fire up android studio and create a new compose project:

New Project

Then give the new project a name like "Jetpack Room". Once done click on Finish.

New Project Name

Installing The Dependencies

Next we need to install the dependencies, open up your app's build.gradle file and add the following:

implementation 'androidx.room:room-runtime:2.5.0'
kapt 'androidx.room:room-compiler:2.5.0'

Because we are using the kapt plugin we will also need to add this to the list of plugins in the same file like so:

plugins {
    id 'kotlin-kapt'
}

Next Sync the project and then create a new "MainApplication" and add the following like below the application block like so:

<application
    android:name=".MainApplication" 
>
</application>

Now that we have the project set up we can finally start coding. 😄

Creating The Room Database

First we will be creating the database in order to store todos on the user's phone, this will make it so that the todos aren't deleted when the user destroys the application.

If you didn't know Room provides an abstraction layer over SQLite to allow for a more robust database access while harnessing the full power of SQLite.

Create a new "db" package to handle the Database operations and create a new file called "AppDatabase" and fill the file with the following:

package com.example.jetpackroom.db

import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters

@Database(entities = [Todo::class], version = 1, exportSchema = false)
@TypeConverters(DateTimeConverter::class)
abstract class AppDatabase : RoomDatabase() {
    abstract fun todoDao(): TodoDao

    companion object {
        const val NAME = "todos"
    }
}

Here we create a Room Database object, don't worrying about the class doesn't exist errors etc as we will be creating them as well. The database will manage a Todo class, with a version of one and since we don't really need to export the schema we also set "exportSchema" to false.

We also use a TypeConverter to handle dates, (Room doesn't handle dates very well).

We also finally name the database "todos".

Next we need to create the TypeConverter so create a new file called "DateTimeConverter" and flesh it with the following:

package com.example.jetpackroom.db

import androidx.room.TypeConverter
import java.util.*

class DateTimeConverter {
    @TypeConverter
    fun fromTimestamp(value: Long?): Date? {
        return value?.let { Date(it) }
    }

    @TypeConverter
    fun dateToTimestamp(date: Date?): Long? {
        return date?.time?.toLong()
    }
}

In this class we provide a way for Room to handle dates, here we just give two methods, one to get the date from the timestamp and one to convert the date back to timestamp.

Next we need to create the Todo entity that we provided to the AppDatabase, open up another file called "Todo" and fill it with the following:

package com.example.jetpackroom.db

import androidx.room.Entity
import androidx.room.PrimaryKey
import java.util.Date

@Entity(tableName = "todos")
data class Todo(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    val title: String,
    val created_at: Date = Date()
)

Here all of the previous errors should have gone away. Here we set the Entity table name to "todos", it has a primary key of id which auto increments, a title and when it was created. Pretty simple Todo.

Next we need a DAO (Data Access Object) which will enable us to query the database. Create a new file called "TodoDao" and fill it with the following contents:

package com.example.jetpackroom.db

import androidx.room.*

@Dao
interface TodoDao {
    @Query("select * from todos order by created_at asc")
    fun getAll(): MutableList<Todo>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun post(todo: Todo)

    @Delete
    fun delete(todo: Todo)
}

This class will allow us to communicate with the database, here we have three methods, one for getting all of the Todos from the database, one to insert into the database if there is a conflict we just replace the old todo and finally one method to delete the todo from the database.

Now that we have the database side of things sorted what's the point of having it if you don't use it. ☺️

Create A Simple Todo Application

Finally we now get to use the code we coding in the previous section. 😆

Open up "MainActivity" and fill it with the following:

package com.example.jetpackroom

import android.app.Application
import androidx.room.Room
import com.example.jetpackroom.db.AppDatabase

class MainApplication : Application() {
    companion object {
        lateinit var database: AppDatabase
    }

    override fun onCreate() {
        super.onCreate()

        database = Room.databaseBuilder(
            applicationContext,
            AppDatabase::class.java,
            AppDatabase.NAME
        ).build()
    }
}

Here we basically use the MainApplication class to initialize the database object.

Finally all we need to do now is edit "MainActivity", open it up and change it to the following:

package com.example.jetpackroom

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.platform.SoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.example.jetpackroom.db.Todo
import com.example.jetpackroom.ui.theme.JetpackRoomTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class MainActivity : ComponentActivity() {
    private val dao = MainApplication.database.todoDao()
    private var todoList = mutableStateListOf<Todo>()
    private var scope = MainScope()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            JetpackRoomTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    MainScreen(todoList = todoList)
                    loadToDo()
                }
            }
        }
    }

    private fun loadToDo() {
        scope.launch {
            withContext(Dispatchers.Default) {
                dao.getAll().forEach { todo ->
                    todoList.add(todo)
                }
            }
        }
    }

    private fun postTodo(title: String) {
        scope.launch {
            withContext(Dispatchers.Default) {
                dao.post(Todo(title = title))

                todoList.clear()
                loadToDo()
            }
        }
    }

    private fun deleteTodo(todo: Todo) {
        scope.launch {
            withContext(Dispatchers.Default) {
                dao.delete(todo)

                todoList.clear()
                loadToDo()
            }
        }
    }

    @OptIn(ExperimentalComposeUiApi::class)
    @Composable
    fun MainScreen(todoList: SnapshotStateList<Todo>) {
        val context = LocalContext.current
        val keyboardController: SoftwareKeyboardController? = LocalSoftwareKeyboardController.current
        var text: String by remember {
            mutableStateOf("")
        }

        Column(
            modifier = Modifier.clickable {
                keyboardController?.hide()
            }
        ) {
            TopAppBar(
                title = { Text(text = stringResource(id = R.string.main_title)) }
            )
            LazyColumn(modifier = Modifier
                .fillMaxWidth()
                .weight(1f)) {

                items(todoList) { todo ->
                    key(todo.id) {
                        TodoItem(
                            todo = todo,
                            onClick = {
                                deleteTodo(todo)
                            }
                        )
                    }
                }
            }
            Row(modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp)) {

                OutlinedTextField(
                    value = text,
                    onValueChange = { text = it },
                    colors = TextFieldDefaults.textFieldColors(
                        backgroundColor = Color.Transparent,
                        focusedIndicatorColor = Color.Transparent,
                        unfocusedIndicatorColor = Color.Transparent
                    ),
                    modifier = Modifier.border(
                        BorderStroke(2.dp, Color.Gray)
                    ),
                    label = { Text(text = stringResource(id = R.string.main_new_todo)) }
                )

                Spacer(modifier = Modifier.size(16.dp))

                Button(
                    onClick = {
                        if (text.isEmpty()) return@Button

                        postTodo(text)
                        text = ""
                    },
                    modifier = Modifier.align(Alignment.CenterVertically)
                ) {
                    Text(text = stringResource(id = R.string.main_add_todo))
                }
            }
        }
    }
}

This UI is pretty simple it shows a list of all the todo objects, and provided a text area that allows you to input text, once done click the Add button to add the todo to the list and database. You can also click on the object to delete it.

Also note the todo persists even if the user restarts the application.

Now we have a simple Todo application. 😃

Todo App

Conclusion

Here I have shown how to create a simple todo application using Android Jetpack Compose, I hoped this has helped you. 😁

Feel free to try and implementing todo updating or try playing around with the UI.

Heppy Coding! 😎

As always you find the repository via:
https://github.com/ethand91/android-compose-todo

Like me work? I post about a variety of topics, if you would like to see more please like and follow me.
Also I love coffee.

“Buy Me A Coffee”

If you are looking to learn Algorithm Patterns to ace the coding interview I recommend the following course

...



📌 What’s New with Android Jetpack and Jetpack Compose


📈 46.72 Punkte

📌 Jetpack Compose Mastery Series Finale: 38 Key Issues in Compose UI


📈 43.14 Punkte

📌 Learn Jetpack Compose at a Compose Camp near you!


📈 43.14 Punkte

📌 Learn Jetpack Compose at Compose Camp


📈 43.14 Punkte

📌 Writing cleaner Jetpack Compose code with the Twitter Compose Ruleset


📈 43.14 Punkte

📌 Jetpack Compose Mastery Part 1: A Comprehensive Guide to Building Your First Compose Application


📈 43.14 Punkte

📌 Jetpack Compose Mastery Part 2: Advanced Tools and Resources for Mastering Compose UI


📈 43.14 Punkte

📌 CVE-2021-40895 | todo-regex 0.1.1 TODO Statement incorrect regex


📈 36.99 Punkte

📌 Now in Android: 35 - Jetpack Compose Beta, Android 12, WorkManager, and more!


📈 34.14 Punkte

📌 Now in Android: 40 - Google I/O 2021, Jetpack Compose, Android 12 beta, and more!


📈 34.14 Punkte

📌 Now in Android: 65 - Android 13 Beta 4, Jetpack Compose 1.2 stable, Wear OS, and more!


📈 34.14 Punkte

📌 Now in Android: 93 - Android 14, Wear OS 4, Gestures in Jetpack Compose, and more!


📈 34.14 Punkte

📌 Now in Android: 69 - Compose Camp, MAD Skills Compose, Android Studio Dolphin, and more!


📈 33.08 Punkte

📌 What's New in Jetpack Compose (Android Dev Summit '19)


📈 31.63 Punkte

📌 #AskAndroid at Android Dev Summit 2019 - Jetpack Compose


📈 31.63 Punkte

📌 A modern approach to Android development, with Jetpack Compose and more!


📈 31.63 Punkte

📌 Jetpack Compose: Android bekommt neues UI-Framework


📈 31.63 Punkte

📌 Now in Android: 24 - Jetpack Compose Alpha, ConstraintLayout 2.0, articles, videos, and more!


📈 31.63 Punkte

📌 The next step in modern Android development: Jetpack Compose


📈 31.63 Punkte

📌 Deklarative UI-Entwicklung für Android: Jetpack Compose erreicht Beta-Status


📈 31.63 Punkte

📌 Jetpack Compose: Neues Framework für Android-UI ist komplett


📈 31.63 Punkte

📌 3 things to know about Jetpack Compose from Android Dev Summit 2019


📈 31.63 Punkte

📌 Google to developers: Our Kotlin-based Jetpack Compose will let you build Android apps faster


📈 31.63 Punkte

📌 Android 12 preview, Jetpack Compose Beta, Cloud Domains, and more!


📈 31.63 Punkte

📌 Designing for accessibility in Android Studio and Jetpack Compose


📈 31.63 Punkte

📌 Jetpack Compose is now 1.0: announcing Android’s modern toolkit for building native UI


📈 31.63 Punkte

📌 Android Developer Story: Airbnb uses Jetpack Compose to empower devs to do their best work


📈 31.63 Punkte

📌 Google: Jetpack Compose Lets Android Developers Write Apps With 'Dramatically Less Code'


📈 31.63 Punkte

📌 Jetpack Compose: Neues Framework für Android-UI ist komplett


📈 31.63 Punkte

📌 Now in Android: 80 - Media3, Jetpack Compose 1.4, Crash Management, and more!


📈 31.63 Punkte

📌 Android-UI-Toolkit: Jetpack Compose 1.6 legt den Fokus auf höhere Performance


📈 31.63 Punkte

📌 Android-UI-Toolkit: Jetpack Compose 1.6 legt den Fokus auf höhere Performance


📈 31.63 Punkte

📌 Android Dev Challenge: lift off with Jetpack Compose


📈 31.63 Punkte

📌 Android-Entwicklung: UI-Toolkit Jetpack Compose arbeitet mit aktuellem Kotlin


📈 31.63 Punkte

📌 Now in Android: 64 - Independent versioning of Jetpack Compose libraries, and more!


📈 31.63 Punkte











matomo