Skip to content

Commit

Permalink
Add source code
Browse files Browse the repository at this point in the history
  • Loading branch information
Abrynos committed Feb 5, 2021
1 parent 3afada7 commit 9cb1b07
Show file tree
Hide file tree
Showing 55 changed files with 1,210 additions and 0 deletions.
56 changes: 56 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-android-extensions'
id 'kotlin-kapt'
}

android {
compileSdkVersion 30
buildToolsVersion "30.0.2"

defaultConfig {
applicationId "pl.edu.pjwstk.s999844.shoppinglist"
minSdkVersion 24
targetSdkVersion 30
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding = true
}
}

dependencies {
implementation 'androidx.lifecycle:lifecycle-process:2.2.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.3'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.3'
def room_version = "2.2.6"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation fileTree(include: ['*.jar'], dir: 'libs')

implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.1'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
21 changes: 21 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Binary file added app/release/app-release.apk
Binary file not shown.
18 changes: 18 additions & 0 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": 2,
"artifactType": {
"type": "APK",
"kind": "Directory"
},
"applicationId": "pl.edu.pjwstk.s999844.shoppinglist",
"variantName": "processReleaseResources",
"elements": [
{
"type": "SINGLE",
"filters": [],
"versionCode": 1,
"versionName": "1.0",
"outputFile": "app-release.apk"
}
]
}
31 changes: 31 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pl.edu.pjwstk.s999844.shoppinglist">

<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/appName"
android:logo="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ShoppingList">
<activity
android:name=".AddItemActivity"
android:parentActivityName=".MainActivity" />
<activity
android:name=".OptionsActivity"
android:parentActivityName=".MainActivity" />
<activity
android:name=".MainActivity"
android:logo="@drawable/ic_trash"
android:theme="@style/Theme.ShoppingList.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Binary file added app/src/main/ic_launcher-playstore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package pl.edu.pjwstk.s999844.shoppinglist

import android.os.Bundle
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.activity_add_item.*
import pl.edu.pjwstk.s999844.shoppinglist.dal.ShoppingListDao
import pl.edu.pjwstk.s999844.shoppinglist.dal.ShoppingListDatabase
import pl.edu.pjwstk.s999844.shoppinglist.models.RequiredItem


class AddItemActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_item)
}

override fun onStart() {
super.onStart()

title = getString(R.string.addTitleBarText)
}

@Suppress("UNUSED_PARAMETER")
fun addItem(view: View) {
val name: String = addItemNameInput.text.toString().trim()
if (name.isEmpty()) {
warnError(getString(R.string.addNameIsEmptyMessage))
return
}

val amountString = addItemAmountInput.text.toString().trim()
val amount: Int = if (amountString.isEmpty() || amountString.isBlank()) {
1
} else {
try {
amountString.toInt()
} catch (e: NumberFormatException) {
warnError(getString(R.string.addAmountNotANumberMessage))
return
}
}

if (amount <= 0) {
warnError(getString(R.string.addAmountTooSmallMessage))
return
}

val shoppingListDao: ShoppingListDao =
ShoppingListDatabase.getInstance(applicationContext).getShoppingListDao();

if (shoppingListDao.findByNameLike(name).isNotEmpty()) {
warnError(getString(R.string.addItemAlreadyExistsMessage))
return
}

val item = RequiredItem(name, amount)
shoppingListDao.add(item)

finish()
}

private fun warnError(message: String) =
Snackbar.make(saveButton, message, Snackbar.LENGTH_SHORT).show()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package pl.edu.pjwstk.s999844.shoppinglist

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
import pl.edu.pjwstk.s999844.shoppinglist.dal.ShoppingListDao
import pl.edu.pjwstk.s999844.shoppinglist.dal.ShoppingListDatabase
import pl.edu.pjwstk.s999844.shoppinglist.models.RequiredItem
import pl.edu.pjwstk.s999844.shoppinglist.recyclerviewadapters.ShoppingListAdapter
import pl.edu.pjwstk.s999844.shoppinglist.settings.Settings


class MainActivity : AppCompatActivity() {
private val settings: Settings by lazy { Settings(this) }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

initItemList()
}

private fun initItemList() {
mainListRecyclerView.layoutManager = LinearLayoutManager(this)
mainListRecyclerView.addItemDecoration(
DividerItemDecoration(
this,
DividerItemDecoration.VERTICAL
)
)

val shoppingListDao: ShoppingListDao =
ShoppingListDatabase.getInstance(applicationContext).getShoppingListDao();
shoppingListDao.findAllItems().observe(this, {
it.let {
(mainListRecyclerView.adapter as ShoppingListAdapter).setItems(it)
if (it.isEmpty()) {
mainListRecyclerView.visibility = View.GONE
mainEmptyTextView.visibility = View.VISIBLE
} else {
mainListRecyclerView.visibility = View.VISIBLE
mainEmptyTextView.visibility = View.GONE
}
}
})
mainListRecyclerView.adapter = ShoppingListAdapter { item, change ->
val dbItem: RequiredItem = shoppingListDao.findById(item.id)
?: return@ShoppingListAdapter

val newAmount: Int = dbItem.amount + change
if (newAmount <= 0) {
shoppingListDao.delete(item)
} else {
item.amount = newAmount
shoppingListDao.update(item)
}
}
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
return true
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.actionBarMenuOptionsEntry -> {
openActivity(OptionsActivity::class.java)
return true
}
}
return super.onOptionsItemSelected(item)
}

@Suppress("UNUSED_PARAMETER")
fun onClickFloatingButton(view: View) = openActivity(AddItemActivity::class.java)

private fun <T : Activity> openActivity(clazz: Class<T>) =
startActivity(Intent(baseContext, clazz))

override fun onStart() {
super.onStart()

ThemeManager.set(settings.darkThemeActive)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package pl.edu.pjwstk.s999844.shoppinglist

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SwitchCompat
import kotlinx.android.synthetic.main.activity_options.*
import pl.edu.pjwstk.s999844.shoppinglist.settings.Settings


class OptionsActivity : AppCompatActivity() {
private val settings: Settings by lazy { Settings(this) }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_options)
}

override fun onStart() {
super.onStart()

optionsThemeSwitch.isChecked = settings.darkThemeActive
optionsThemeSwitch.setOnClickListener {
it as SwitchCompat
onThemeSwitched(it.isChecked)
}

title = getString(R.string.optionsTitleBarText)
}

private fun onThemeSwitched(isDark: Boolean) {
settings.darkThemeActive = isDark
ThemeManager.set(isDark)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package pl.edu.pjwstk.s999844.shoppinglist

import androidx.appcompat.app.AppCompatDelegate

object ThemeManager {
fun set(dark: Boolean) {
AppCompatDelegate.setDefaultNightMode(if (dark) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package pl.edu.pjwstk.s999844.shoppinglist.dal

import androidx.lifecycle.LiveData
import androidx.room.*
import pl.edu.pjwstk.s999844.shoppinglist.models.RequiredItem

@Dao
interface ShoppingListDao {
@Query("SELECT * FROM RequiredItem")
fun findAllItems(): LiveData<List<RequiredItem>>

@Query("SELECT * FROM RequiredItem WHERE name LIKE :name")
fun findByNameLike(name: String): List<RequiredItem>

@Query("SELECT * FROM RequiredItem WHERE id LIKE :id")
fun findById(id: Long): RequiredItem?

@Insert
fun add(item: RequiredItem)

@Update
fun update(item: RequiredItem)

@Delete
fun delete(item: RequiredItem)
}
Loading

0 comments on commit 9cb1b07

Please sign in to comment.