diff --git a/app/build.gradle b/app/build.gradle index 335d9cc..609f0dc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,21 +4,22 @@ apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 30 - buildToolsVersion "30.0.1" + buildToolsVersion "30.0.2" defaultConfig { applicationId "me.zobrist.tichucounter" minSdkVersion 16 targetSdkVersion 30 - versionCode 1 - versionName "1.0" + versionCode 7 + versionName "1.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { - minifyEnabled false + minifyEnabled true + shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } @@ -37,11 +38,14 @@ dependencies { implementation 'androidx.core:core-ktx:1.3.1' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.2.0' - implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation 'com.google.android.play:core:1.8.0' + implementation 'com.google.android.play:core-ktx:1.8.1' + implementation 'com.google.code.gson:gson:2.8.5' + implementation 'androidx.constraintlayout:constraintlayout:2.0.1' implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0' implementation 'androidx.navigation:navigation-ui-ktx:2.3.0' testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test.ext:junit:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + 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/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d7ced19..e35f381 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,7 +8,8 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" - android:theme="@style/AppTheme"> + android:theme="@style/AppTheme" + android:fullBackupContent="@xml/backup_descriptor"> = ArrayList() - constructor(parcel: Parcel) : this() { - scores = parcel.readSerializable() as ArrayList - } - fun getScoreA(): Int { var tempScore = 0 scores.forEach { @@ -31,7 +25,7 @@ class History() : Parcelable { fun getHistoryA(): String { var tempHistory = String() scores.forEach { - tempHistory = tempHistory.plus(it.scoreA.toString()).plus("\n") + tempHistory += it.scoreA.toString() + "\n" } return tempHistory } @@ -39,7 +33,7 @@ class History() : Parcelable { fun getHistoryB(): String { var tempHistory = String() scores.forEach { - tempHistory = tempHistory.plus(it.scoreB.toString()).plus("\n") + tempHistory += it.scoreB.toString() + "\n" } return tempHistory } @@ -61,23 +55,4 @@ class History() : Parcelable { fun isEmpty(): Boolean { return scores.isEmpty() } - - override fun writeToParcel(parcel: Parcel, flags: Int) { - parcel.writeSerializable(scores) - } - - override fun describeContents(): Int { - return 0 - } - - companion object CREATOR : Parcelable.Creator { - override fun createFromParcel(parcel: Parcel): History { - return History(parcel) - } - - override fun newArray(size: Int): Array { - return arrayOfNulls(size) - } - } - } \ No newline at end of file diff --git a/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt b/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt index 7da4264..4a8f94e 100644 --- a/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt +++ b/app/src/main/java/me/zobrist/tichucounter/MainActivity.kt @@ -6,17 +6,17 @@ import android.os.Bundle import android.text.InputType import android.view.Menu import android.view.MenuItem +import android.view.WindowManager +import android.view.inputmethod.InputMethodManager import android.widget.ScrollView import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.core.widget.doOnTextChanged +import com.google.gson.Gson import kotlinx.android.synthetic.main.content_main.* class MainActivity : AppCompatActivity() { - private var invertA: Boolean = false - private var invertB: Boolean = false - private var updateOnChange: Boolean = true private lateinit var history: History @@ -31,11 +31,30 @@ class MainActivity : AppCompatActivity() { inputTeamA.requestFocus() disableSubmitButton() updateTheme(this.getSharedPreferences("Settings", Context.MODE_PRIVATE).getInt("Theme", 2)) + keepScreenOn( + this.getSharedPreferences("Settings", Context.MODE_PRIVATE) + .getBoolean("Screen_On", false) + ) - history = savedInstanceState?.getParcelable("history") ?: History() + val json = this.getSharedPreferences("Settings", Context.MODE_PRIVATE).getString("history", "{\"scores\":[]}") + history = Gson().fromJson(json, History::class.java) + nameTeamA.setText(this.getSharedPreferences("Settings", Context.MODE_PRIVATE).getString("nameTeamA", "TeamA")) + nameTeamB.setText(this.getSharedPreferences("Settings", Context.MODE_PRIVATE).getString("nameTeamB", "TeamB")) updateView() + inputTeamA.setOnFocusChangeListener { view, b -> + if (b) { + hideKeyboard() + } + } + + inputTeamB.setOnFocusChangeListener { view, b -> + if (b) { + hideKeyboard() + } + } + inputTeamA.doOnTextChanged { text, start, count, after -> if (inputTeamA.isFocused) { if (inputTeamA.text.isNotEmpty()) { @@ -44,21 +63,21 @@ class MainActivity : AppCompatActivity() { Round(text.toString().toInt(), true) } catch (e: java.lang.Exception) { - Round(0, 0) + Round(1, 1) } inputTeamB.setText(currentRound.scoreB.toString()) - }else{ + } else { updateOnChange = true } - }else{ + } else { inputTeamA.text.clear() inputTeamB.text.clear() } } - if(currentRound.isValidRound()){ + if (currentRound.isValidRound() && inputTeamA.text.isNotEmpty() && inputTeamB.text.isNotEmpty()) { enableSubmitButton() - }else{ + } else { disableSubmitButton() } } @@ -67,80 +86,89 @@ class MainActivity : AppCompatActivity() { inputTeamB.doOnTextChanged { text, start, count, after -> if (inputTeamB.isFocused) { - if (inputTeamB.text.isNotEmpty()){ - if(updateOnChange){ + if (inputTeamB.text.isNotEmpty()) { + if (updateOnChange) { currentRound = try { Round(text.toString().toInt(), false) - } catch (e: java.lang.Exception){ - Round(0, 0) + } catch (e: java.lang.Exception) { + Round(1, 1) } inputTeamA.setText(currentRound.scoreA.toString()) - }else{ + } else { updateOnChange = true } - }else{ + } else { inputTeamA.text.clear() inputTeamB.text.clear() } } - if(currentRound.isValidRound()){ + if (currentRound.isValidRound() && inputTeamA.text.isNotEmpty() && inputTeamB.text.isNotEmpty()) { enableSubmitButton() - }else{ + } else { disableSubmitButton() } } buttonAdd100.setOnClickListener { + giveFocusToAIfNone() + if (inputTeamA.isFocused) { - val temp = try { + currentRound.scoreA = try { inputTeamA.text.toString().toInt() + 100 } catch (e: Exception) { - inputTeamB.setText(0.toString()) + currentRound.scoreB = 0 + inputTeamB.setText(currentRound.scoreB.toString()) 100 - } updateOnChange = false - inputTeamA.setText(temp.toString()) + inputTeamA.setText(currentRound.scoreA.toString()) } if (inputTeamB.isFocused) { - val temp = try { + currentRound.scoreB = try { inputTeamB.text.toString().toInt() + 100 } catch (e: Exception) { - inputTeamA.setText(0.toString()) + currentRound.scoreA = 0 + inputTeamA.setText(currentRound.scoreA.toString()) 100 } updateOnChange = false - inputTeamB.setText(temp.toString()) + inputTeamB.setText(currentRound.scoreB.toString()) + } } buttonSub100.setOnClickListener { + giveFocusToAIfNone() + if (inputTeamA.isFocused) { - val temp = try { + currentRound.scoreA = try { inputTeamA.text.toString().toInt() - 100 } catch (e: Exception) { + currentRound.scoreB = 0 + inputTeamB.setText(currentRound.scoreB.toString()) -100 } updateOnChange = false - inputTeamA.setText(temp.toString()) - + inputTeamA.setText(currentRound.scoreA.toString()) } if (inputTeamB.isFocused) { - val temp = try { + currentRound.scoreB = try { inputTeamB.text.toString().toInt() - 100 } catch (e: Exception) { + currentRound.scoreA = 0 + inputTeamA.setText(currentRound.scoreA.toString()) -100 } updateOnChange = false - inputTeamB.setText(temp.toString()) + inputTeamB.setText(currentRound.scoreB.toString()) } } @@ -199,23 +227,29 @@ class MainActivity : AppCompatActivity() { giveFocusToAIfNone() - if(inputTeamA.isFocused ){ - if (inputTeamA.text.isNotEmpty()){ + if (inputTeamA.isFocused) { + if (inputTeamA.text.toString().equals("-")) { + inputTeamA.text.clear() + } else if (inputTeamA.text.isNotEmpty()) { tempInt = inputTeamA.text.toString().toInt() * -1 inputTeamA.setText(tempInt.toString()) - }else{ - invertB = false - invertA = true + } else { + updateOnChange = false + appendToFocusedInput('-') + currentRound = Round(1,1) } - }else if(inputTeamB.isFocused) { - if(inputTeamB.text.isNotEmpty()){ + } else if (inputTeamB.isFocused) { + if (inputTeamB.text.toString().equals("-")) { + inputTeamB.text.clear() + } else if (inputTeamB.text.isNotEmpty()) { tempInt = inputTeamB.text.toString().toInt() * -1 inputTeamB.setText(tempInt.toString()) - } else{ - invertA = false - invertB = true + } else { + updateOnChange = false + appendToFocusedInput('-') + currentRound = Round(1,1) } } } @@ -242,36 +276,62 @@ class MainActivity : AppCompatActivity() { if (inputTeamA.text.isNotEmpty() && inputTeamB.text.isNotEmpty()) { - history.logRound(Round(inputTeamA.text.toString().toInt(), inputTeamB.text.toString().toInt())) - + history.logRound( + Round( + inputTeamA.text.toString().toInt(), + inputTeamB.text.toString().toInt() + ) + ) updateView() - inputTeamA.text.clear() inputTeamB.text.clear() + disableSubmitButton() scrollViewHistory.fullScroll(ScrollView.FOCUS_DOWN) - } } } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) - outState.putParcelable("history", history) + + val prefs = this.getSharedPreferences("Settings", Context.MODE_PRIVATE).edit() + prefs.putString("history", Gson().toJson(history)) + prefs.putString("nameTeamA", nameTeamA.text.toString()) + prefs.putString("nameTeamB", nameTeamB.text.toString()) + prefs.apply() + } override fun onCreateOptionsMenu(menu: Menu): Boolean { // Inflate the menu; this adds items to the action bar if it is present. menuInflater.inflate(R.menu.menu_main, menu) + + menu.findItem(R.id.action_screenOn).isChecked = + this.getSharedPreferences("Settings", Context.MODE_PRIVATE) + .getBoolean("Screen_On", false) return true } + override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.action_clear -> { - clearAll() + val builder = AlertDialog.Builder(this) + builder.setMessage(getString(R.string.confirmClear)) + .setTitle(R.string.clear) + .setCancelable(false) + .setPositiveButton(getString(R.string.yes)) { dialog, id -> + dialog.dismiss() + clearAll() + } + .setNegativeButton(getString(R.string.no)) { dialog, id -> + dialog.cancel() + } + + builder.create().show() true } R.id.action_undo -> { @@ -282,10 +342,21 @@ class MainActivity : AppCompatActivity() { chooseThemeDialog() true } + R.id.action_screenOn -> { + item.isChecked = !item.isChecked + keepScreenOn(item.isChecked) + true + } else -> super.onOptionsItemSelected(item) } } + private fun hideKeyboard() { + val imm: InputMethodManager = + getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager + imm.hideSoftInputFromWindow(currentFocus!!.windowToken, 0) + } + private fun giveFocusToAIfNone() { if (!inputTeamA.isFocused && !inputTeamB.isFocused) { inputTeamA.requestFocus() @@ -293,10 +364,8 @@ class MainActivity : AppCompatActivity() { } private fun undoLastRound() { - history.revertLastRound() updateView() - } private fun updateView() { @@ -318,24 +387,12 @@ class MainActivity : AppCompatActivity() { history.clearAll() } - private fun appendToFocusedInput(toAppend: Char){ - if(inputTeamA.isFocused){ - if(invertA){ - invertA = false - inputTeamA.text.append('-') - } - + private fun appendToFocusedInput(toAppend: Char) { + if (inputTeamA.isFocused) { inputTeamA.text.append(toAppend) - }else if(inputTeamB.isFocused) - { - if(invertB){ - invertB = false - inputTeamB.text.append('-') - } + } else if (inputTeamB.isFocused) { inputTeamB.text.append(toAppend) } - - } private fun enableSubmitButton() { @@ -343,7 +400,7 @@ class MainActivity : AppCompatActivity() { submit.isEnabled = true } - private fun disableSubmitButton(){ + private fun disableSubmitButton() { submit.imageAlpha = 60 // 0 being transparent and 255 being opaque submit.isEnabled = false } @@ -352,9 +409,10 @@ class MainActivity : AppCompatActivity() { val builder = AlertDialog.Builder(this) builder.setTitle(getString(R.string.choose_theme_text)) - val styles = arrayOf("Light","Dark","System default") + val styles = arrayOf("Light", "Dark", "System default") - val checkedItem = this.getSharedPreferences("", Context.MODE_PRIVATE).getInt("Theme", 2) + val checkedItem = + this.getSharedPreferences("Settings", Context.MODE_PRIVATE).getInt("Theme", 2) val prefs = this.getSharedPreferences("Settings", Context.MODE_PRIVATE).edit() @@ -381,4 +439,16 @@ class MainActivity : AppCompatActivity() { } delegate.applyDayNight() } + + private fun keepScreenOn(keepOn: Boolean) { + if (keepOn) { + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + } else { + window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + } + + val prefs = this.getSharedPreferences("Settings", Context.MODE_PRIVATE).edit() + prefs.putBoolean("Screen_On", keepOn) + prefs.apply() + } } \ No newline at end of file diff --git a/app/src/main/java/me/zobrist/tichucounter/Round.kt b/app/src/main/java/me/zobrist/tichucounter/Round.kt index fad6b61..3f0b7f6 100644 --- a/app/src/main/java/me/zobrist/tichucounter/Round.kt +++ b/app/src/main/java/me/zobrist/tichucounter/Round.kt @@ -1,6 +1,8 @@ package me.zobrist.tichucounter -class Round() { +import java.io.Serializable + +class Round() : Serializable { var scoreA: Int = 0 var scoreB: Int = 0 diff --git a/app/src/main/res/layout-land/content_main.xml b/app/src/main/res/layout-land/content_main.xml index de790fa..a205dec 100644 --- a/app/src/main/res/layout-land/content_main.xml +++ b/app/src/main/res/layout-land/content_main.xml @@ -17,13 +17,13 @@ app:layout_constraintTop_toTopOf="parent"> + android:textAppearance="@style/TextAppearance.AppCompat.Large" /> + android:textAppearance="@style/TextAppearance.AppCompat.Large" /> @@ -66,7 +66,8 @@ android:gravity="center" android:text="0" android:textAppearance="@style/TextAppearance.AppCompat.Body1" - android:textSize="18sp" /> + android:textSize="18sp" + android:textStyle="bold" /> + android:textSize="18sp" + android:textStyle="bold" /> @@ -84,7 +86,8 @@ android:id="@+id/scrollViewHistory" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginTop="16dp"> + android:layout_marginTop="16dp" + android:clickable="false"> @@ -270,7 +273,8 @@ android:paddingTop="15dp" android:paddingBottom="15dp" android:scaleType="fitCenter" - app:srcCompat="@drawable/back" /> + app:srcCompat="@drawable/back" + android:contentDescription="TODO" /> @@ -309,7 +313,8 @@ android:layout_height="match_parent" android:layout_weight="1.0" android:scaleType="fitCenter" - app:srcCompat="@drawable/checkmark" /> + app:srcCompat="@drawable/checkmark" + android:contentDescription="TODO" /> diff --git a/app/src/main/res/layout/content_main.xml b/app/src/main/res/layout/content_main.xml index c014338..4b36db1 100644 --- a/app/src/main/res/layout/content_main.xml +++ b/app/src/main/res/layout/content_main.xml @@ -7,14 +7,14 @@ app:layout_behavior="@string/appbar_scrolling_view_behavior"> + android:textAppearance="@style/TextAppearance.AppCompat.Large" /> + android:textAppearance="@style/TextAppearance.AppCompat.Large" /> + app:layout_constraintTop_toBottomOf="@+id/viewNames"> + android:textSize="18sp" + android:textStyle="bold" /> + android:textSize="18sp" + android:textStyle="bold" /> @@ -84,8 +86,8 @@ android:layout_width="match_parent" android:layout_height="0dp" android:layout_marginTop="16dp" - app:layout_constraintBottom_toTopOf="@+id/Input" - app:layout_constraintTop_toBottomOf="@+id/Score"> + app:layout_constraintBottom_toTopOf="@+id/viewInput" + app:layout_constraintTop_toBottomOf="@+id/viewScore"> + app:layout_constraintBottom_toBottomOf="@+id/viewScore" /> + app:srcCompat="@drawable/back" + android:contentDescription="TODO" /> @@ -314,6 +317,7 @@ android:layout_height="match_parent" android:layout_weight="1.0" android:scaleType="fitCenter" - app:srcCompat="@drawable/checkmark" /> + app:srcCompat="@drawable/checkmark" + android:contentDescription="TODO" /> \ No newline at end of file diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml index 779bead..dd7f051 100644 --- a/app/src/main/res/menu/menu_main.xml +++ b/app/src/main/res/menu/menu_main.xml @@ -17,4 +17,9 @@ android:id="@+id/action_theme" android:orderInCategory="15" android:title="@string/choose_theme_text" /> + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 560610f..aa8ffe5 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -1,6 +1,10 @@ - Neues Spiel Starten - Letzte Runde Löschen + Neues Spiel starten + Letzte Runde löschen Theme auswählen + Bildschirm eingeschaltet lassen + Möchten Sie das laufende Spiel wirklich löschen? + Ja + Nein \ No newline at end of file diff --git a/app/src/main/res/values-gsw-rCH/strings.xml b/app/src/main/res/values-gsw-rCH/strings.xml index c8d4afd..3559d30 100644 --- a/app/src/main/res/values-gsw-rCH/strings.xml +++ b/app/src/main/res/values-gsw-rCH/strings.xml @@ -1,6 +1,10 @@ - Neus Spil Starte - Letschti Rundi Lösche + Neus Spil starte + Letschti Rundi lösche Usgsehe ändere + Bildschirm igschalted la + Wosch ds loufende Spil würklech lösche? + Ja + Nei \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0e770fb..0944156 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4,7 +4,11 @@ Team A Team B - Start New Game - Undo Last Round + Start new game + Undo last round Choose theme + Keep screen on + Do you really want to delete the current game? + Yes + No \ No newline at end of file diff --git a/app/src/main/res/xml/backup_descriptor.xml b/app/src/main/res/xml/backup_descriptor.xml new file mode 100644 index 0000000..6fd6103 --- /dev/null +++ b/app/src/main/res/xml/backup_descriptor.xml @@ -0,0 +1,4 @@ + + + + diff --git a/build.gradle b/build.gradle index 1241d12..33d6ece 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = "1.3.72" + ext.kotlin_version = "1.4.10" repositories { google() jcenter()