diff --git a/TodoList/.gitignore b/TodoList/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/TodoList/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/TodoList/app/.gitignore b/TodoList/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/TodoList/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/TodoList/app/build.gradle b/TodoList/app/build.gradle new file mode 100644 index 0000000..034aa10 --- /dev/null +++ b/TodoList/app/build.gradle @@ -0,0 +1,46 @@ +plugins { + id 'com.android.application' + id 'kotlin-android' +} + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.2" + + defaultConfig { + applicationId "com.sem.todolist" + minSdkVersion 16 + 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' + } +} + +dependencies { + + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation 'androidx.core:core-ktx:1.2.0' + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'com.google.android.material:material:1.1.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'com.google.code.gson:gson:2.8.6' + testImplementation 'junit:junit:4.+' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' +} \ No newline at end of file diff --git a/TodoList/app/proguard-rules.pro b/TodoList/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/TodoList/app/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/TodoList/app/src/androidTest/java/com/sem/todolist/ExampleInstrumentedTest.kt b/TodoList/app/src/androidTest/java/com/sem/todolist/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..73f217f --- /dev/null +++ b/TodoList/app/src/androidTest/java/com/sem/todolist/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.sem.todolist + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.sem.todolist", appContext.packageName) + } +} \ No newline at end of file diff --git a/TodoList/app/src/main/AndroidManifest.xml b/TodoList/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8bb87d7 --- /dev/null +++ b/TodoList/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TodoList/app/src/main/java/com/sem/todolist/DataSingleton.kt b/TodoList/app/src/main/java/com/sem/todolist/DataSingleton.kt new file mode 100644 index 0000000..1d7d57f --- /dev/null +++ b/TodoList/app/src/main/java/com/sem/todolist/DataSingleton.kt @@ -0,0 +1,50 @@ +package com.sem.todolist + +import android.content.Context +import android.content.SharedPreferences +import android.util.Log +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken + +class DataSingleton() { + + var items: ArrayList = ArrayList() + lateinit var appContext: Context + lateinit var preferences: SharedPreferences + lateinit var editor: SharedPreferences.Editor + + fun initialize(context: Context) { + this.appContext = context + preferences = context.getSharedPreferences("USER",Context.MODE_PRIVATE) + editor = preferences.edit() + } + + private object HOLDER { + val INSTANCE = DataSingleton() + } + + companion object { + val instance: DataSingleton by lazy { HOLDER.INSTANCE } + } + + //saving list in Shared Preference + fun save(){ + val gson = Gson() + val json = gson.toJson(items)//converting list to Json + + editor.putString("LIST",json) + editor.commit() + } + //getting the list from shared preference + fun load(){ + val gson = Gson() + val json = preferences.getString("LIST",null) + items = if (json != null) { + val type = object : TypeToken>(){}.type//converting the json to list + Log.d("data singleton","from json: " + gson.fromJson(json,type)) + gson.fromJson(json,type) + } else { + ArrayList() + } + } +} \ No newline at end of file diff --git a/TodoList/app/src/main/java/com/sem/todolist/MainActivity.kt b/TodoList/app/src/main/java/com/sem/todolist/MainActivity.kt new file mode 100644 index 0000000..68c0351 --- /dev/null +++ b/TodoList/app/src/main/java/com/sem/todolist/MainActivity.kt @@ -0,0 +1,58 @@ +package com.sem.todolist + +import android.content.DialogInterface +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.text.InputType +import android.util.Log +import android.view.View +import android.widget.EditText +import android.widget.ImageView +import androidx.appcompat.app.AlertDialog +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView + +class MainActivity : AppCompatActivity() { + lateinit var adapter: TodoItemAdapter + lateinit var todoItems: ArrayList; + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + val rc: RecyclerView = findViewById(R.id.itemRecyclerView) + todoItems = DataSingleton.instance.items; + adapter = TodoItemAdapter(todoItems, this) + rc.layoutManager = LinearLayoutManager(this) + rc.adapter = adapter + + DataSingleton.instance.initialize(this) + DataSingleton.instance.load() + + } + + fun addItem(view: View) { + Log.i("MAINACTIVITY", "adding new item") + val builder = AlertDialog.Builder(this) + builder.setTitle("Enter new task name") + val input = EditText(this) + input.inputType = InputType.TYPE_CLASS_TEXT + builder.setView(input) + + builder.setPositiveButton("Yee") { dialog, i -> + run { + DataSingleton.instance.items.add(TodoItem(input.text.toString())) + Log.d("MAINACTIVITY DIALOG", "items: " + DataSingleton.instance.items) + todoItems = DataSingleton.instance.items; + Log.d("MAINACTIVITY DIALOG", "todo items: " + DataSingleton.instance.items) + adapter.notifyDataSetChanged() + } + } + + builder.setNegativeButton("Nah") { dialog, which -> + Log.i("MAINACTIVITY DIALOG", "nah button pressed") + } + + builder.show() + + } +} \ No newline at end of file diff --git a/TodoList/app/src/main/java/com/sem/todolist/TodoItem.kt b/TodoList/app/src/main/java/com/sem/todolist/TodoItem.kt new file mode 100644 index 0000000..986aedf --- /dev/null +++ b/TodoList/app/src/main/java/com/sem/todolist/TodoItem.kt @@ -0,0 +1,12 @@ +package com.sem.todolist + +class TodoItem(title: String) { + var done: Boolean = false; + var title: String = title + + override fun toString(): String { + return "todo item::: $title + $done" + } + + +} \ No newline at end of file diff --git a/TodoList/app/src/main/java/com/sem/todolist/TodoItemAdapter.kt b/TodoList/app/src/main/java/com/sem/todolist/TodoItemAdapter.kt new file mode 100644 index 0000000..1abc7c6 --- /dev/null +++ b/TodoList/app/src/main/java/com/sem/todolist/TodoItemAdapter.kt @@ -0,0 +1,31 @@ +package com.sem.todolist + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.CheckBox +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView + +class TodoItemAdapter(private val dataSet: ArrayList, val context: Context) : RecyclerView.Adapter(){ + val appContext: Context = context + + class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { + val textView: TextView = view.findViewById(R.id.itemText) + val checkBox: CheckBox = view.findViewById(R.id.itemCheckbox) + + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val view = LayoutInflater.from(parent.context).inflate(R.layout.todo_item,parent,false) + return ViewHolder(view) + } + + override fun getItemCount(): Int = dataSet.size + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.textView.text = dataSet[position].title + holder.checkBox.isChecked = dataSet[position].done + } +} \ No newline at end of file diff --git a/TodoList/app/src/main/res/anim/splash_in.xml b/TodoList/app/src/main/res/anim/splash_in.xml new file mode 100644 index 0000000..253fa05 --- /dev/null +++ b/TodoList/app/src/main/res/anim/splash_in.xml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/TodoList/app/src/main/res/anim/splash_out.xml b/TodoList/app/src/main/res/anim/splash_out.xml new file mode 100644 index 0000000..2db4605 --- /dev/null +++ b/TodoList/app/src/main/res/anim/splash_out.xml @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/TodoList/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/TodoList/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/TodoList/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/TodoList/app/src/main/res/drawable/ic_launcher_background.xml b/TodoList/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/TodoList/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TodoList/app/src/main/res/drawable/list.png b/TodoList/app/src/main/res/drawable/list.png new file mode 100644 index 0000000..ec590d7 Binary files /dev/null and b/TodoList/app/src/main/res/drawable/list.png differ diff --git a/TodoList/app/src/main/res/layout/todo_item.xml b/TodoList/app/src/main/res/layout/todo_item.xml new file mode 100644 index 0000000..41c58fa --- /dev/null +++ b/TodoList/app/src/main/res/layout/todo_item.xml @@ -0,0 +1,32 @@ + + + + + + + \ No newline at end of file diff --git a/TodoList/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/TodoList/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/TodoList/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/TodoList/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/TodoList/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/TodoList/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/TodoList/app/src/main/res/mipmap-hdpi/ic_launcher.png b/TodoList/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..a571e60 Binary files /dev/null and b/TodoList/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/TodoList/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/TodoList/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000..61da551 Binary files /dev/null and b/TodoList/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/TodoList/app/src/main/res/mipmap-mdpi/ic_launcher.png b/TodoList/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..c41dd28 Binary files /dev/null and b/TodoList/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/TodoList/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/TodoList/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000..db5080a Binary files /dev/null and b/TodoList/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/TodoList/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/TodoList/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..6dba46d Binary files /dev/null and b/TodoList/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/TodoList/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/TodoList/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000..da31a87 Binary files /dev/null and b/TodoList/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/TodoList/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/TodoList/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..15ac681 Binary files /dev/null and b/TodoList/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/TodoList/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/TodoList/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..b216f2d Binary files /dev/null and b/TodoList/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/TodoList/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/TodoList/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..f25a419 Binary files /dev/null and b/TodoList/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/TodoList/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/TodoList/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000..e96783c Binary files /dev/null and b/TodoList/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/TodoList/app/src/main/res/values-night/themes.xml b/TodoList/app/src/main/res/values-night/themes.xml new file mode 100644 index 0000000..fa50ea3 --- /dev/null +++ b/TodoList/app/src/main/res/values-night/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/TodoList/app/src/main/res/values/colors.xml b/TodoList/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/TodoList/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/TodoList/app/src/main/res/values/strings.xml b/TodoList/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..16cf03b --- /dev/null +++ b/TodoList/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Todo list + \ No newline at end of file diff --git a/TodoList/app/src/main/res/values/themes.xml b/TodoList/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..5cffd5f --- /dev/null +++ b/TodoList/app/src/main/res/values/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/TodoList/app/src/test/java/com/sem/todolist/ExampleUnitTest.kt b/TodoList/app/src/test/java/com/sem/todolist/ExampleUnitTest.kt new file mode 100644 index 0000000..c7c7195 --- /dev/null +++ b/TodoList/app/src/test/java/com/sem/todolist/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.sem.todolist + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} \ No newline at end of file diff --git a/TodoList/build.gradle b/TodoList/build.gradle new file mode 100644 index 0000000..ea6e2ae --- /dev/null +++ b/TodoList/build.gradle @@ -0,0 +1,26 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + ext.kotlin_version = "1.3.72" + repositories { + google() + jcenter() + } + dependencies { + classpath "com.android.tools.build:gradle:4.1.1" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} \ No newline at end of file diff --git a/TodoList/gradle.properties b/TodoList/gradle.properties new file mode 100644 index 0000000..98bed16 --- /dev/null +++ b/TodoList/gradle.properties @@ -0,0 +1,21 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app"s APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true +# Kotlin code style for this project: "official" or "obsolete": +kotlin.code.style=official \ No newline at end of file diff --git a/TodoList/gradle/wrapper/gradle-wrapper.jar b/TodoList/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..f6b961f Binary files /dev/null and b/TodoList/gradle/wrapper/gradle-wrapper.jar differ diff --git a/TodoList/gradle/wrapper/gradle-wrapper.properties b/TodoList/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..212180a --- /dev/null +++ b/TodoList/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Dec 01 21:22:11 CET 2020 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip diff --git a/TodoList/gradlew b/TodoList/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/TodoList/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/TodoList/gradlew.bat b/TodoList/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/TodoList/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/TodoList/settings.gradle b/TodoList/settings.gradle new file mode 100644 index 0000000..e441c45 --- /dev/null +++ b/TodoList/settings.gradle @@ -0,0 +1,2 @@ +include ':app' +rootProject.name = "Todo list" \ No newline at end of file diff --git a/TodoTitemsV2/.gitignore b/TodoTitemsV2/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/TodoTitemsV2/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/TodoTitemsV2/app/.gitignore b/TodoTitemsV2/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/TodoTitemsV2/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/TodoTitemsV2/app/build.gradle b/TodoTitemsV2/app/build.gradle new file mode 100644 index 0000000..1b1eae5 --- /dev/null +++ b/TodoTitemsV2/app/build.gradle @@ -0,0 +1,49 @@ +plugins { + id 'com.android.application' +} + +android { + compileSdkVersion 30 + buildToolsVersion "30.0.2" + + defaultConfig { + applicationId "com.sem.todotitemsv2" + minSdkVersion 19 + 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 + } +} + +dependencies { + + // Java language implementation + implementation "androidx.fragment:fragment:1.2.5" + + // safe args + apply plugin: "androidx.navigation.safeargs" + + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'com.google.android.material:material:1.2.1' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'com.google.code.gson:gson:2.8.6' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.navigation:navigation-fragment:2.3.3' + implementation 'androidx.navigation:navigation-ui:2.3.3' + testImplementation 'junit:junit:4.13.1' + androidTestImplementation 'androidx.test.ext:junit:1.1.2' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' +} \ No newline at end of file diff --git a/TodoTitemsV2/app/proguard-rules.pro b/TodoTitemsV2/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/TodoTitemsV2/app/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/TodoTitemsV2/app/src/androidTest/java/com/sem/todotitemsv2/ExampleInstrumentedTest.java b/TodoTitemsV2/app/src/androidTest/java/com/sem/todotitemsv2/ExampleInstrumentedTest.java new file mode 100644 index 0000000..97f5178 --- /dev/null +++ b/TodoTitemsV2/app/src/androidTest/java/com/sem/todotitemsv2/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.sem.todotitemsv2; + +import android.content.Context; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.sem.todotitemsv2", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/TodoTitemsV2/app/src/main/AndroidManifest.xml b/TodoTitemsV2/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..16653cd --- /dev/null +++ b/TodoTitemsV2/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/Data.java b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/Data.java new file mode 100644 index 0000000..bc31f7e --- /dev/null +++ b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/Data.java @@ -0,0 +1,93 @@ +package com.sem.todotitemsv2; + +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Observer; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; + +public enum Data { + INSTANCE; + + private MutableLiveData> items; + private Context appContext; + private final String TAG = Data.class.getCanonicalName(); + + public void addForeverItemObserver(Observer> observer) { + this.items.observeForever(observer); + } + + public void removeForeverItemObserver(Observer> observer) { + this.items.removeObserver(observer); + } + + public MutableLiveData> getItems() { + Log.d(TAG, "getItems: getting items!"); + return items; + } + + public void init(Context appContext) { + Log.d(TAG, "init: initing data singleton"); + this.appContext = appContext; + + this.items = new MutableLiveData<>(); + setItems(IO.loadLists(appContext)); + + } + + public TodoList getList(int pos) { + return this.items.getValue().get(pos); + } + + public void renameList(String newName, int todoListPosition) { + this.items.getValue().get(todoListPosition).setName(newName); + updateItems(); + } + + public void addTodoItem(int todoListIndex, TodoItem item) { + this.items.getValue().get(todoListIndex).getItems().add(item); + updateItems(); + } + + public void removeTodoItem(int todoListIndex, TodoItem item) { + this.items.getValue().get(todoListIndex).getItems().remove(item); + updateItems(); + } + + public void checkTodoItem(int todoListIndex, int todoItemIndex) { + this.items.getValue().get(todoListIndex).getItems().get(todoItemIndex).check(); + updateItems(); + } + + public void addItem(TodoList item) { + this.items.getValue().add(item); + updateItems(); + } + + public void removeItem(TodoList item) { + this.items.getValue().remove(item); + updateItems(); + } + + private void updateItems() { + this.items.postValue(this.items.getValue()); + } + + public void setItems(ArrayList items) { + this.items.postValue(items); + } + + + public void save() { + IO.saveLists(appContext,this.items.getValue()); + } +} diff --git a/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/IO.java b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/IO.java new file mode 100644 index 0000000..b667cd3 --- /dev/null +++ b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/IO.java @@ -0,0 +1,86 @@ +package com.sem.todotitemsv2; + +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; +import android.view.View; +import android.widget.TextView; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import java.util.ArrayList; +import java.util.Arrays; + +public class IO { + private static final String TAG = IO.class.getCanonicalName(); + private static final String ITEMS_SIZE_ID = "Items_Size"; + private static final String SP_NAME = "USER"; + private static final String JSON_NAME = "Json_List_Items"; + + public static void save(Context context, ArrayList items) { + SharedPreferences sharedPreferences = context.getSharedPreferences(SP_NAME,Context.MODE_PRIVATE); + Log.d(TAG, "Saving shared preferences"); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putInt(ITEMS_SIZE_ID,items.size()); + for (int i = 0; i < items.size(); i++) { + editor.remove("item" + i + "title"); + editor.putString("item"+i+"title",items.get(i).getTitle()); + editor.remove("item" + i + "done"); + editor.putBoolean("item"+i+"done",items.get(i).isDone()); + } + + editor.apply(); + } + + public static void saveLists(Context context, ArrayList items) { + SharedPreferences sharedPreferences = context.getSharedPreferences(SP_NAME,Context.MODE_PRIVATE); + Log.d(TAG, "Saving shared preferences"); + SharedPreferences.Editor editor = sharedPreferences.edit(); + + Gson gson = new Gson(); + String jsonLists = gson.toJson(items); + editor.putString(JSON_NAME,jsonLists); + editor.apply(); + } + + public static ArrayList loadLists(Context context) { + SharedPreferences sharedPreferences = context.getSharedPreferences(SP_NAME,Context.MODE_PRIVATE); + Log.d(TAG, "Saving shared preferences"); + + Gson gson = new Gson(); + ArrayList res = gson.fromJson(sharedPreferences.getString(JSON_NAME,""),new TypeToken>() {}.getType()); + return res == null ? new ArrayList<>() : res; + } + + public static ArrayList load(Context context) { + SharedPreferences sharedPreferences = context.getSharedPreferences(SP_NAME,Context.MODE_PRIVATE); + Log.d(TAG, "Loading shared preferences"); + int amount = sharedPreferences.getInt(ITEMS_SIZE_ID,0); + Log.d(TAG, "amount " + amount); + ArrayList items = new ArrayList<>(); + if (amount > 0) { + for (int i = 0; i < amount; i++) { + String title = sharedPreferences.getString("item" + i + "title","item" + i); + boolean done = sharedPreferences.getBoolean("item" + i + "done",false); + items.add(new TodoItem(title,done)); + } + } + Log.d(TAG, "List: " + Arrays.toString(items.toArray())); + return items; + + } + + public static void clear(Context context) { + SharedPreferences sharedPreferences = context.getSharedPreferences(SP_NAME,Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.clear(); + editor.apply(); + } + + public static void Log(String text, View view) { +// TextView textView = view.findViewById(R.id.logView); +// textView.setText(text); + + } +} diff --git a/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/ItemsFragment.java b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/ItemsFragment.java new file mode 100644 index 0000000..28f3858 --- /dev/null +++ b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/ItemsFragment.java @@ -0,0 +1,87 @@ +package com.sem.todotitemsv2; + +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link ItemsFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class ItemsFragment extends Fragment { + + private final static String TAG = ItemsFragment.class.getCanonicalName(); + + public ItemsFragment() { + // Required empty public constructor + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @return A new instance of fragment ItemsFragment. + */ + // TODO: Rename and change types and number of parameters + public static ItemsFragment newInstance() { + return new ItemsFragment(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Log.d(TAG, "onCreate: creating items fragment!"); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_items, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + + Log.d(TAG, "onViewCreated: created!"); + int pos = getArguments().getInt("todo_item_position"); + Log.d(TAG, "onViewCreated: got argument: " + pos); + TodoList current = Data.INSTANCE.getList(pos); + + ((AppCompatActivity)requireActivity()).getSupportActionBar().setTitle(current.getName()); + ((AppCompatActivity)requireActivity()).getSupportActionBar().setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.done))); + + RecyclerView recyclerView = view.findViewById(R.id.items_list_recyclerview); + + TodoItemAdaper todoItemAdaper = new TodoItemAdaper(current.getItemsAsList()); + + recyclerView.setLayoutManager(new LinearLayoutManager(requireContext())); + recyclerView.setAdapter(todoItemAdaper); + + //TODO add layout to xml file + //TODO add back button + //TODO add functionality for adding and removing and editing + } + + @Override + public void onResume() { + + Log.d(TAG, "onResume: RESUMED"); + super.onResume(); + } +} \ No newline at end of file diff --git a/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/MainActivity.java b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/MainActivity.java new file mode 100644 index 0000000..9a82a98 --- /dev/null +++ b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/MainActivity.java @@ -0,0 +1,62 @@ +package com.sem.todotitemsv2; + +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import android.content.Context; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.view.ViewParent; +import android.widget.EditText; +import android.widget.TextView; + +import java.util.ArrayList; +import java.util.Arrays; + +public class MainActivity extends AppCompatActivity { + private final String TAG = MainActivity.class.getCanonicalName(); + private TodoItemAdaper mAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + Data.INSTANCE.init(this); + + Log.d(TAG, "onCreate: setting overview fragment transaction"); + if (savedInstanceState == null) { + getSupportFragmentManager().beginTransaction() + .setReorderingAllowed(true) + .add(R.id.fragment_container_view, OverviewFragment.class, null) + .commit(); + } + +// RecyclerView rc = findViewById(R.id.itemRecyclerView); +// ArrayList items = Data.INSTANCE.getItems(); +// mAdapter = new TodoItemAdaper(items); +// rc.setLayoutManager(new LinearLayoutManager(this)); +// rc.setAdapter(mAdapter); + + } + + + + @Override + protected void onPause() { + super.onPause(); + + Data.INSTANCE.save(); + } + + + @FunctionalInterface + public interface OverviewNavigationListener { + void onNavigate(); + } +} \ No newline at end of file diff --git a/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/OverviewFragment.java b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/OverviewFragment.java new file mode 100644 index 0000000..c1fa9af --- /dev/null +++ b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/OverviewFragment.java @@ -0,0 +1,152 @@ +package com.sem.todotitemsv2; + +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.os.Build; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.Observer; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.navigation.fragment.NavHostFragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.Toast; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; + +import java.util.ArrayList; +import java.util.List; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link OverviewFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class OverviewFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener { + + private static final String TAG = OverviewFragment.class.getCanonicalName(); + private TodoListAdapter mAdapter; + private SwipeRefreshLayout mSwipeRefreshLayout; + private RecyclerView rc; + + private final Observer> itemsObserver = todoListList -> { + this.mAdapter.setItems(todoListList); + Log.d(TAG, "onViewCreated: updated items in recyclerview adapter"); + Toast.makeText(requireContext(),"Updated todo lists!",Toast.LENGTH_SHORT).show(); + }; + + public OverviewFragment() { + // Required empty public constructor + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @return A new instance of fragment OverviewFragment. + */ + public static OverviewFragment newInstance() { + return new OverviewFragment(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Log.d(TAG, "onCreate: CREATING OVERVIEW FRAGMENT"); + + + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + + return inflater.inflate(R.layout.fragment_overview, container, false); + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + ((AppCompatActivity)requireActivity()).getSupportActionBar().setTitle("Todo Lists Overview"); + ((AppCompatActivity)requireActivity()).getSupportActionBar().setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.done))); + + rc = view.findViewById(R.id.overview_recyclerview); + Log.d(TAG, "onCreateView: " + rc); + + Data.INSTANCE.addForeverItemObserver(this.itemsObserver); + + mAdapter = new TodoListAdapter(Data.INSTANCE.getItems().getValue()); + mAdapter.setOnTodoListClickListener(this::onItemClick); + + rc.setLayoutManager(new LinearLayoutManager(requireContext())); + rc.setAdapter(mAdapter); + + mSwipeRefreshLayout = view.findViewById(R.id.swipe_refresh_layout); + mSwipeRefreshLayout.setOnRefreshListener(this); + + FloatingActionButton floatingActionButton = view.findViewById(R.id.floating_action_button_add); + floatingActionButton.setOnClickListener(this::addNewListItem); + + //TODO add button for renaming a list + } + + private void addNewListItem(View view) { + Log.i(TAG, "adding new item"); + AlertDialog.Builder builder = new AlertDialog.Builder(requireContext()); + builder.setTitle("Enter new task name:"); + EditText input = new EditText(requireContext()); + builder.setView(input); + + builder.setPositiveButton("Yee", (dialog, which) -> { + // add item to list and update + Data.INSTANCE.addItem(new TodoList(input.getText().toString())); + Log.d(TAG, "items: " + Data.INSTANCE.getItems()); + + }).setNegativeButton("Nah", (dialog, which) -> { + // do nothing + }); + builder.create(); + builder.show(); + } + + @Override + public void onRefresh() { + mAdapter.setItems(Data.INSTANCE.getItems().getValue()); + mSwipeRefreshLayout.setRefreshing(false); + } + + + public void onItemClick(View view) { + int position = rc.getChildLayoutPosition(view); + Log.d(TAG, "onItemClick: clicked item " + position); + Bundle bundle = new Bundle(); + bundle.putInt("todo_item_position",position); + + getActivity().getSupportFragmentManager().beginTransaction() + .setReorderingAllowed(true) + .replace(R.id.fragment_container_view, ItemsFragment.class, bundle) + .commit(); + + + } + +} \ No newline at end of file diff --git a/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/TodoItem.java b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/TodoItem.java new file mode 100644 index 0000000..8c60054 --- /dev/null +++ b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/TodoItem.java @@ -0,0 +1,43 @@ +package com.sem.todotitemsv2; + +public class TodoItem { + private boolean done; + private String title; + + public TodoItem(String title) { + this(title,false); + } + + public TodoItem(String title, boolean done) { + this.title = title; + this.done = done; + } + + public String getTitle() { + return title; + } + + public boolean isDone() { + return done; + } + + public void setDone(boolean done) { + this.done = done; + } + + public void setTitle(String title) { + this.title = title; + } + + public void check() { + this.done = !this.done; + } + + @Override + public String toString() { + return "TodoItem{" + + "done=" + done + + ", title='" + title + '\'' + + '}'; + } +} diff --git a/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/TodoItemAdaper.java b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/TodoItemAdaper.java new file mode 100644 index 0000000..b0f292f --- /dev/null +++ b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/TodoItemAdaper.java @@ -0,0 +1,86 @@ +package com.sem.todotitemsv2; + +import android.graphics.Color; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; + +public class TodoItemAdaper extends RecyclerView.Adapter { + private final String TAG = TodoItemAdaper.class.getCanonicalName(); + + private ArrayList items; + int pos; + public TodoItemAdaper(ArrayList todoItems) { + this.items = todoItems; + } + + + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + private TextView textView; + private CheckBox checkBox; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + textView = itemView.findViewById(R.id.itemText); + checkBox = itemView.findViewById(R.id.itemCheckbox); + itemView.setOnClickListener(this); + + } + + public CheckBox getCheckBox() { + return checkBox; + } + + public TextView getTextView() { + return textView; + } + + @Override + public void onClick(View v) { + Log.d(TAG, "Clicked on recyclerview item"); +// Data.INSTANCE.getItems().get(pos).click(); + notifyDataSetChanged(); + } + } + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.todo_item,parent,false)); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + this.pos = position; + holder.getTextView().setText(this.items.get(position).getTitle()); + holder.getCheckBox().setChecked(this.items.get(position).isDone()); + if (this.items.get(position).isDone()) { + holder.getTextView().setTextColor(getIntFromColor(56,61,61)); + } else { + holder.getTextView().setTextColor(getIntFromColor(1,135,134)); + } + } + + @Override + public int getItemCount() { + return this.items.size(); + } + + public int getIntFromColor(int Red, int Green, int Blue){ + Red = (Red << 16) & 0x00FF0000; //Shift red 16-bits and mask out other stuff + Green = (Green << 8) & 0x0000FF00; //Shift Green 8-bits and mask out other stuff + Blue = Blue & 0x000000FF; //Mask out anything not blue. + + return 0xFF000000 | Red | Green | Blue; //0xFF000000 for 100% Alpha. Bitwise OR everything together. + } + +} diff --git a/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/TodoList.java b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/TodoList.java new file mode 100644 index 0000000..cc71003 --- /dev/null +++ b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/TodoList.java @@ -0,0 +1,38 @@ +package com.sem.todotitemsv2; + +import java.util.ArrayList; +import java.util.List; + +public class TodoList { + private String name; + private List items; + + public TodoList(String name) { + this.items = new ArrayList<>(); + this.name = name; + } + + public List getItems() { + return items; + } + + public ArrayList getItemsAsList() { + return (ArrayList) this.items; + } + + public void setItems(List items) { + this.items = items; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getItemsSize() { + return this.items.size(); + } +} diff --git a/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/TodoListAdapter.java b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/TodoListAdapter.java new file mode 100644 index 0000000..2fbf5a9 --- /dev/null +++ b/TodoTitemsV2/app/src/main/java/com/sem/todotitemsv2/TodoListAdapter.java @@ -0,0 +1,102 @@ +package com.sem.todotitemsv2; + +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.List; + +public class TodoListAdapter extends RecyclerView.Adapter { + + private static final String TAG = TodoListAdapter.class.getCanonicalName(); + private List items; + private View.OnClickListener onTodoListClickListener; + + public static class ViewHolder extends RecyclerView.ViewHolder { + private final TextView listNameTextView; + private final ImageButton listDeleteButton; + private final TextView listSizeTextView; + + public ViewHolder(@NonNull View itemView) { + super(itemView); + + listNameTextView = itemView.findViewById(R.id.overview_list_item_text); + listDeleteButton = itemView.findViewById(R.id.overview_list_delete_button); + listSizeTextView = itemView.findViewById(R.id.overview_list_size); + } + + public ImageButton getListDeleteButton() { + return listDeleteButton; + } + + public TextView getListNameTextView() { + return listNameTextView; + } + + public TextView getListSizeTextView() { + return listSizeTextView; + } + + } + + public TodoListAdapter(List list) { + this.items = list; + } + + public void setOnTodoListClickListener(View.OnClickListener onTodoListClickListener) { + this.onTodoListClickListener = onTodoListClickListener; + } + + public void setItems(List items) { + Log.d(TAG, "setItems: setting items in adapter to " + items); + this.items = items; + notifyDataSetChanged(); + } + + + @NonNull + @Override + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.todo_list_item,parent,false); + view.setOnClickListener(this.onTodoListClickListener); + + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull ViewHolder holder, int position) { + + holder.getListNameTextView().setText(this.items.get(position).getName()); + holder.getListSizeTextView().setText(this.items.get(position).getItemsSize() + " items"); + holder.getListDeleteButton().setOnClickListener(v -> { + deleteListItem(position); + }); + + } + + private void deleteListItem(int pos) { + Log.d(TAG, "deleteListItem: deleting list item! at position " + pos); + Data.INSTANCE.removeItem(this.items.get(pos)); + } + + @Override + public int getItemCount() { + return items.size(); + } + + + + @FunctionalInterface + public interface OnTodoListClickListener { + void onItemClick(View view, int position); + } +} diff --git a/TodoTitemsV2/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/TodoTitemsV2/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/TodoTitemsV2/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/TodoTitemsV2/app/src/main/res/drawable/ic_baseline_add_24.xml b/TodoTitemsV2/app/src/main/res/drawable/ic_baseline_add_24.xml new file mode 100644 index 0000000..eb23254 --- /dev/null +++ b/TodoTitemsV2/app/src/main/res/drawable/ic_baseline_add_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/TodoTitemsV2/app/src/main/res/drawable/ic_baseline_delete_24.xml b/TodoTitemsV2/app/src/main/res/drawable/ic_baseline_delete_24.xml new file mode 100644 index 0000000..3c4030b --- /dev/null +++ b/TodoTitemsV2/app/src/main/res/drawable/ic_baseline_delete_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/TodoTitemsV2/app/src/main/res/drawable/ic_baseline_refresh_24.xml b/TodoTitemsV2/app/src/main/res/drawable/ic_baseline_refresh_24.xml new file mode 100644 index 0000000..f2be45b --- /dev/null +++ b/TodoTitemsV2/app/src/main/res/drawable/ic_baseline_refresh_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/TodoTitemsV2/app/src/main/res/drawable/ic_launcher_background.xml b/TodoTitemsV2/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/TodoTitemsV2/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TodoTitemsV2/app/src/main/res/layout/activity_main.xml b/TodoTitemsV2/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..ff83e12 --- /dev/null +++ b/TodoTitemsV2/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TodoTitemsV2/app/src/main/res/layout/fragment_items.xml b/TodoTitemsV2/app/src/main/res/layout/fragment_items.xml new file mode 100644 index 0000000..9a80517 --- /dev/null +++ b/TodoTitemsV2/app/src/main/res/layout/fragment_items.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/TodoTitemsV2/app/src/main/res/layout/fragment_overview.xml b/TodoTitemsV2/app/src/main/res/layout/fragment_overview.xml new file mode 100644 index 0000000..ff8a392 --- /dev/null +++ b/TodoTitemsV2/app/src/main/res/layout/fragment_overview.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/TodoTitemsV2/app/src/main/res/layout/todo_item.xml b/TodoTitemsV2/app/src/main/res/layout/todo_item.xml new file mode 100644 index 0000000..b238076 --- /dev/null +++ b/TodoTitemsV2/app/src/main/res/layout/todo_item.xml @@ -0,0 +1,50 @@ + + + + + + + + +