Skip to content

Commit 25f2927

Browse files
committed
✨ chore(README): add README.md with project information and setup instructions
Signed-off-by: Dmytro Turskyi <dmytro.turskyi@gmail.com>
1 parent 952f968 commit 25f2927

12 files changed

Lines changed: 104 additions & 38 deletions

File tree

README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner-direct-single.svg)](https://stand-with-ukraine.pp.ua)
2+
<img alt="GitHub commit activity" src="https://img.shields.io/github/commit-activity/m/Turskyi/TaskList">
3+
4+
# TaskList App
5+
6+
A sample Android application demonstrating the use of Android Room database
7+
for task management.
8+
9+
## Features:
10+
11+
- Add tasks with high, middle, or low priority
12+
- Delete tasks by swiping left or right
13+
- Simple and intuitive interface
14+
- **Code Readability:** code is easily readable with no unnecessary blank lines,
15+
no unused variables
16+
or methods, and no commented-out code, all variables, methods, and resource
17+
IDs are descriptively
18+
named such that another developer reading the code can easily understand their
19+
function.
20+
21+
## Technologies Used:
22+
23+
- [Android](https://developer.android.com/studio/intro)
24+
- [Kotlin](https://kotlinlang.org/)
25+
- [Monolithic Architecture](https://en.wikipedia.org/wiki/Monolithic_architecture)
26+
- AndroidX Room (room-ktx)
27+
- View Model
28+
29+
## Getting Started:
30+
31+
1. Download the project
32+
2. Open in Android Studio
33+
3. Run on an emulator or Android device
34+
35+
## Usage:
36+
37+
- Use the app as a regular task manager
38+
- Explore the code to learn about Android Room implementation
39+
40+
## Contributing:
41+
42+
Contributions are welcome! Create a pull request to the master branch.
43+
44+
## License:
45+
46+
No intentional license was used for this project.
47+
48+
## Contact:
49+
50+
Dmytro Turskyi
51+
52+
[dmytro@turskyi.com](mailto:dmytro@turskyi.com)
53+
54+
https://github.com/Turskyi
55+
56+
Note: Since this is a sample app, it's not intended for production use or
57+
publication on Google Play.
58+
59+
## Screenshots:
60+
61+
<!--suppress CheckImageSize -->
62+
<img src="screenshots/AddTaskScreenshot_20240724.png" width="200" alt="screenshot">
63+
<img src="screenshots/tasks_Screenshot_20240724.png" width="200" alt="screenshot">

app/build.gradle

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@ plugins {
55
}
66

77
android {
8-
compileSdkVersion 30
9-
buildToolsVersion "30.0.2"
8+
compileSdkVersion 34
109

1110
defaultConfig {
1211
applicationId "io.github.turskyi.tasklist"
1312
minSdkVersion 21
14-
targetSdkVersion 30
13+
targetSdkVersion 34
1514
versionCode 1
1615
versionName "1.0"
1716

@@ -31,29 +30,30 @@ android {
3130
kotlinOptions {
3231
jvmTarget = '1.8'
3332
}
33+
namespace 'io.github.turskyi.tasklist'
3434
}
3535

3636
dependencies {
3737
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
38-
implementation 'androidx.core:core-ktx:1.3.2'
39-
implementation 'androidx.appcompat:appcompat:1.2.0'
40-
implementation 'com.google.android.material:material:1.3.0'
41-
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
42-
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.3'
43-
implementation 'androidx.navigation:navigation-ui-ktx:2.3.3'
38+
implementation 'androidx.core:core-ktx:1.13.1'
39+
implementation 'androidx.appcompat:appcompat:1.7.0'
40+
implementation 'com.google.android.material:material:1.12.0'
41+
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
42+
implementation 'androidx.navigation:navigation-fragment-ktx:2.7.7'
43+
implementation 'androidx.navigation:navigation-ui-ktx:2.7.7'
4444
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
4545

4646
/* Room DB */
47-
def room_version = "2.2.6"
47+
def room_version = "2.6.1"
4848
implementation "androidx.room:room-runtime:$room_version"
4949
kapt "androidx.room:room-compiler:$room_version"
5050

5151
// optional - Room Kotlin Extensions and Coroutines support for Room
5252
implementation "androidx.room:room-ktx:$room_version"
5353

5454
testImplementation 'junit:junit:4.13.2'
55-
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
56-
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
55+
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
56+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
5757

5858
// optional - Room Test helpers
5959
testImplementation "androidx.room:room-testing:$room_version"

app/src/main/AndroidManifest.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3-
package="io.github.turskyi.tasklist">
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
43

54
<application
65
android:allowBackup="true"
@@ -11,6 +10,7 @@
1110
android:theme="@style/Theme.TaskList">
1211
<activity
1312
android:name="io.github.turskyi.tasklist.presentation.features.main.view.MainActivity"
13+
android:exported="true"
1414
android:label="@string/app_name"
1515
android:theme="@style/Theme.TaskList.NoActionBar">
1616
<intent-filter>

app/src/main/java/io/github/turskyi/tasklist/database/AppDatabase.kt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package io.github.turskyi.tasklist.database
22

33
import android.content.Context
4-
import android.util.Log
54
import androidx.room.Database
65
import androidx.room.Room
76
import androidx.room.RoomDatabase
@@ -13,25 +12,19 @@ abstract class AppDatabase : RoomDatabase() {
1312
abstract fun taskDao(): TaskDao?
1413

1514
companion object {
16-
private val LOG_TAG = AppDatabase::class.java.simpleName
1715
private val LOCK = Any()
1816
private const val DATABASE_NAME = "tasklist"
1917
private var sInstance: AppDatabase? = null
2018
fun getInstance(context: Context): AppDatabase {
2119
if (sInstance == null) {
2220
synchronized(LOCK) {
23-
Log.d(
24-
LOG_TAG,
25-
"Creating new database instance"
26-
)
2721
sInstance = Room.databaseBuilder(
2822
context.applicationContext,
2923
AppDatabase::class.java, DATABASE_NAME
3024
)
3125
.build()
3226
}
3327
}
34-
Log.d(LOG_TAG, "Getting the database instance")
3528
return sInstance!!
3629
}
3730
}

app/src/main/java/io/github/turskyi/tasklist/database/TaskDao.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package io.github.turskyi.tasklist.database
22

33
import androidx.lifecycle.LiveData
4-
import androidx.room.*
4+
import androidx.room.Dao
5+
import androidx.room.Delete
6+
import androidx.room.Insert
7+
import androidx.room.OnConflictStrategy
8+
import androidx.room.Query
9+
import androidx.room.Update
510
import io.github.turskyi.tasklist.database.TaskEntry.Companion.TABLE_TASKS
611

712
@Dao
@@ -10,13 +15,13 @@ interface TaskDao {
1015
fun loadAllTasks(): LiveData<List<TaskEntry>?>?
1116

1217
@Insert
13-
fun insertTask(taskEntry: TaskEntry?)
18+
fun insertTask(taskEntry: TaskEntry)
1419

1520
@Update(onConflict = OnConflictStrategy.REPLACE)
16-
fun updateTask(taskEntry: TaskEntry?)
21+
fun updateTask(taskEntry: TaskEntry)
1722

1823
@Delete
19-
fun deleteTask(taskEntry: TaskEntry?)
24+
fun deleteTask(taskEntry: TaskEntry)
2025

2126
@Query("SELECT * FROM $TABLE_TASKS WHERE id = :id")
2227
fun loadTaskById(id: Int): LiveData<TaskEntry?>?

app/src/main/java/io/github/turskyi/tasklist/presentation/features/addtask/viewmodel/AddTaskViewModelFactory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import io.github.turskyi.tasklist.database.AppDatabase
66

77
class AddTaskViewModelFactory(private val mDb: AppDatabase, private val mTaskId: Int) :
88
NewInstanceFactory() {
9-
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
9+
override fun <T : ViewModel> create(modelClass: Class<T>): T {
1010
@Suppress("UNCHECKED_CAST")
1111
return AddTaskViewModel(mDb, mTaskId) as T
1212
}

app/src/main/java/io/github/turskyi/tasklist/presentation/features/main/view/MainActivity.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,15 @@ class MainActivity : AppCompatActivity(), ItemClickListener {
6161
return false
6262
}
6363

64-
/* Called when a user swipes left or right on a ViewHolder */
64+
/* Called when a user swipes left or right on a ViewHolder. */
6565
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
66-
/* implementation of swipe to delete */
66+
/* Implementation of swipe to delete. */
6767
AppExecutors.instance?.diskIO()?.execute {
6868
val position = viewHolder.adapterPosition
6969
val tasks: List<TaskEntry>? = mAdapter?.tasks
70-
mDb?.taskDao()?.deleteTask(tasks?.get(position))
70+
if (tasks != null) {
71+
mDb?.taskDao()?.deleteTask(tasks[position])
72+
}
7173
}
7274
}
7375
}).attachToRecyclerView(mRecyclerView)
@@ -96,9 +98,9 @@ class MainActivity : AppCompatActivity(), ItemClickListener {
9698

9799
private fun setupViewModel() {
98100
val viewModel: MainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
99-
viewModel.tasks?.observe(this, { taskEntries ->
101+
viewModel.tasks?.observe(this) { taskEntries ->
100102
Log.d(TAG, "Updating list of tasks from LiveData in ViewModel")
101103
mAdapter?.tasks = taskEntries
102-
})
104+
}
103105
}
104106
}

build.gradle

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22
buildscript {
3-
ext.kotlin_version = "1.4.31"
3+
ext.kotlin_version = "2.0.0"
44
repositories {
55
google()
6-
jcenter()
6+
mavenCentral()
77
}
88
dependencies {
9-
classpath "com.android.tools.build:gradle:4.1.2"
9+
classpath 'com.android.tools.build:gradle:8.5.1'
1010
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
1111

1212
// NOTE: Do not place your application dependencies here; they belong
@@ -17,10 +17,10 @@ buildscript {
1717
allprojects {
1818
repositories {
1919
google()
20-
jcenter()
20+
mavenCentral()
2121
}
2222
}
2323

24-
task clean(type: Delete) {
24+
tasks.register('clean', Delete) {
2525
delete rootProject.buildDir
2626
}

gradle.properties

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,7 @@ android.useAndroidX=true
1818
# Automatically convert third-party libraries to use AndroidX
1919
android.enableJetifier=true
2020
# Kotlin code style for this project: "official" or "obsolete":
21-
kotlin.code.style=official
21+
kotlin.code.style=official
22+
android.defaults.buildfeatures.buildconfig=true
23+
android.nonTransitiveRClass=false
24+
android.nonFinalResIds=false

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip

0 commit comments

Comments
 (0)