Use single live event to prevent false trigger after rotation. remove hilt (for the moment)
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -22,13 +22,8 @@ import me.zobrist.tichucounter.fragments.KeyboardViewModel
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private var updateOnChange: Boolean = true
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var history: History
|
|
||||||
private var currentRound: Round = Round(null, null)
|
private var currentRound: Round = Round(null, null)
|
||||||
|
|
||||||
private val keyboardViewModel: KeyboardViewModel by viewModels()
|
private val keyboardViewModel: KeyboardViewModel by viewModels()
|
||||||
@@ -58,7 +53,6 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
val json = this.getSharedPreferences("Settings", MODE_PRIVATE)
|
val json = this.getSharedPreferences("Settings", MODE_PRIVATE)
|
||||||
.getString("history", "{\"scores\":[]}")
|
.getString("history", "{\"scores\":[]}")
|
||||||
history = Gson().fromJson(json, History::class.java)
|
|
||||||
binding.contentMain.nameTeamA.setText(
|
binding.contentMain.nameTeamA.setText(
|
||||||
this.getSharedPreferences("Settings", MODE_PRIVATE).getString("nameTeamA", "TeamA")
|
this.getSharedPreferences("Settings", MODE_PRIVATE).getString("nameTeamA", "TeamA")
|
||||||
)
|
)
|
||||||
@@ -66,7 +60,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
this.getSharedPreferences("Settings", MODE_PRIVATE).getString("nameTeamB", "TeamB")
|
this.getSharedPreferences("Settings", MODE_PRIVATE).getString("nameTeamB", "TeamB")
|
||||||
)
|
)
|
||||||
|
|
||||||
keyboardViewModel.scoreA.observe(this, androidx.lifecycle.Observer { value ->
|
keyboardViewModel.scoreA.observe(this) { value ->
|
||||||
val tichu = Tichu()
|
val tichu = Tichu()
|
||||||
|
|
||||||
val oldValue = currentRound.scoreA
|
val oldValue = currentRound.scoreA
|
||||||
@@ -83,9 +77,9 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
keyboardViewModel.setSubmitButtonEnable(tichu.isValidRound(currentRound))
|
keyboardViewModel.setSubmitButtonEnable(tichu.isValidRound(currentRound))
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
keyboardViewModel.scoreB.observe(this, androidx.lifecycle.Observer { value ->
|
keyboardViewModel.scoreB.observe(this) { value ->
|
||||||
val tichu = Tichu()
|
val tichu = Tichu()
|
||||||
|
|
||||||
val oldValue = currentRound.scoreB
|
val oldValue = currentRound.scoreB
|
||||||
@@ -102,28 +96,27 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
keyboardViewModel.setSubmitButtonEnable(tichu.isValidRound(currentRound))
|
keyboardViewModel.setSubmitButtonEnable(tichu.isValidRound(currentRound))
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
keyboardViewModel.submitButtonClicked.observe(this, androidx.lifecycle.Observer {
|
keyboardViewModel.submitButtonClicked.observe(this) {
|
||||||
historyListViewModel.logRound(currentRound)
|
historyListViewModel.logRound(currentRound)
|
||||||
keyboardViewModel.setScoreA(null)
|
keyboardViewModel.setScoreA(null)
|
||||||
keyboardViewModel.setScoreB(null)
|
keyboardViewModel.setScoreB(null)
|
||||||
})
|
}
|
||||||
|
|
||||||
historyListViewModel.totalScoreA.observe(this, androidx.lifecycle.Observer { value ->
|
historyListViewModel.totalScoreA.observe(this) { value ->
|
||||||
binding.contentMain.scoreA.text = value.toString()
|
binding.contentMain.scoreA.text = value.toString()
|
||||||
})
|
}
|
||||||
|
|
||||||
historyListViewModel.totalScoreB.observe(this, androidx.lifecycle.Observer { value ->
|
historyListViewModel.totalScoreB.observe(this) { value ->
|
||||||
binding.contentMain.scoreB.text = value.toString()
|
binding.contentMain.scoreB.text = value.toString()
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
|
|
||||||
val prefs = this.getSharedPreferences("Settings", MODE_PRIVATE).edit()
|
val prefs = this.getSharedPreferences("Settings", MODE_PRIVATE).edit()
|
||||||
prefs.putString("history", Gson().toJson(history))
|
|
||||||
prefs.putString("nameTeamA", binding.contentMain.nameTeamA.text.toString())
|
prefs.putString("nameTeamA", binding.contentMain.nameTeamA.text.toString())
|
||||||
prefs.putString("nameTeamB", binding.contentMain.nameTeamB.text.toString())
|
prefs.putString("nameTeamB", binding.contentMain.nameTeamB.text.toString())
|
||||||
prefs.apply()
|
prefs.apply()
|
||||||
@@ -177,8 +170,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun clearAll() {
|
private fun clearAll() {
|
||||||
|
historyListViewModel.clearAll()
|
||||||
history.clearAll()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,12 @@
|
|||||||
package me.zobrist.tichucounter.fragments
|
package me.zobrist.tichucounter.fragments
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.InputType
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.inputmethod.InputMethodManager
|
|
||||||
import android.widget.EditText
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.lifecycle.Observer
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import me.zobrist.tichucounter.databinding.FragmentHistoryListBinding
|
import me.zobrist.tichucounter.databinding.FragmentHistoryListBinding
|
||||||
import me.zobrist.tichucounter.databinding.FragmentKeyboardBinding
|
|
||||||
|
|
||||||
class HistoryList : Fragment() {
|
class HistoryList : Fragment() {
|
||||||
|
|
||||||
@@ -46,13 +39,17 @@ class HistoryList : Fragment() {
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
|
||||||
viewModel.historyA.observe(viewLifecycleOwner, Observer { text ->
|
viewModel.historyA.observe(viewLifecycleOwner) { text ->
|
||||||
binding.historyA.text = text
|
binding.historyA.text = text
|
||||||
})
|
}
|
||||||
|
|
||||||
viewModel.historyB.observe(viewLifecycleOwner, Observer { text ->
|
viewModel.historyB.observe(viewLifecycleOwner) { text ->
|
||||||
binding.historyB.text = text
|
binding.historyB.text = text
|
||||||
})
|
}
|
||||||
|
|
||||||
|
viewModel.scrollDown.observe(viewLifecycleOwner) {
|
||||||
|
binding.scrollViewHistory.smoothScrollTo(0, binding.scrollViewHistory.height)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package me.zobrist.tichucounter.fragments
|
package me.zobrist.tichucounter.fragments
|
||||||
|
|
||||||
|
import SingleLiveEvent
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -13,6 +14,7 @@ class HistoryListViewModel : ViewModel() {
|
|||||||
private val _totalScoreB: MutableLiveData<Int> = MutableLiveData<Int>()
|
private val _totalScoreB: MutableLiveData<Int> = MutableLiveData<Int>()
|
||||||
private val _historyA: MutableLiveData<String> = MutableLiveData<String>()
|
private val _historyA: MutableLiveData<String> = MutableLiveData<String>()
|
||||||
private val _historyB: MutableLiveData<String> = MutableLiveData<String>()
|
private val _historyB: MutableLiveData<String> = MutableLiveData<String>()
|
||||||
|
private val _scrollDown: SingleLiveEvent<Boolean> = SingleLiveEvent()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -36,6 +38,11 @@ class HistoryListViewModel : ViewModel() {
|
|||||||
return _historyB
|
return _historyB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val scrollDown: LiveData<Boolean>
|
||||||
|
get() {
|
||||||
|
return _scrollDown
|
||||||
|
}
|
||||||
|
|
||||||
private fun getScoreA() {
|
private fun getScoreA() {
|
||||||
var tempScore = 0
|
var tempScore = 0
|
||||||
scores.forEach {
|
scores.forEach {
|
||||||
@@ -47,7 +54,7 @@ class HistoryListViewModel : ViewModel() {
|
|||||||
private fun getScoreB() {
|
private fun getScoreB() {
|
||||||
var tempScore = 0
|
var tempScore = 0
|
||||||
scores.forEach {
|
scores.forEach {
|
||||||
it.scoreB?.let {it -> tempScore += it}
|
it.scoreB?.let { it -> tempScore += it }
|
||||||
}
|
}
|
||||||
_totalScoreB.value = tempScore
|
_totalScoreB.value = tempScore
|
||||||
}
|
}
|
||||||
@@ -68,33 +75,33 @@ class HistoryListViewModel : ViewModel() {
|
|||||||
_historyB.value = tempHistory
|
_historyB.value = tempHistory
|
||||||
}
|
}
|
||||||
|
|
||||||
fun logRound(round: Round) {
|
private fun updateAll() {
|
||||||
scores.add(round.copy())
|
|
||||||
getHistoryA()
|
getHistoryA()
|
||||||
getHistoryB()
|
getHistoryB()
|
||||||
getScoreA()
|
getScoreA()
|
||||||
getScoreB()
|
getScoreB()
|
||||||
|
scrollDown()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun logRound(round: Round) {
|
||||||
|
scores.add(round.copy())
|
||||||
|
updateAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun revertLastRound() {
|
fun revertLastRound() {
|
||||||
if (scores.isNotEmpty()) {
|
if (scores.isNotEmpty()) {
|
||||||
scores.removeAt(scores.size - 1)
|
scores.removeAt(scores.size - 1)
|
||||||
}
|
}
|
||||||
getHistoryA()
|
updateAll()
|
||||||
getHistoryB()
|
}
|
||||||
getScoreA()
|
|
||||||
getScoreB()
|
private fun scrollDown() {
|
||||||
|
_scrollDown.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clearAll() {
|
fun clearAll() {
|
||||||
scores.clear()
|
scores.clear()
|
||||||
|
updateAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isEmpty(): Boolean {
|
|
||||||
return scores.isEmpty()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import android.widget.EditText
|
|||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import me.zobrist.tichucounter.databinding.FragmentKeyboardBinding
|
import me.zobrist.tichucounter.databinding.FragmentKeyboardBinding
|
||||||
|
|
||||||
class Keyboard : Fragment() {
|
class Keyboard : Fragment() {
|
||||||
@@ -56,13 +55,13 @@ class Keyboard : Fragment() {
|
|||||||
if (enabled) enableSubmitButton() else disableSubmitButton()
|
if (enabled) enableSubmitButton() else disableSubmitButton()
|
||||||
})
|
})
|
||||||
|
|
||||||
viewModel.scoreA.observe(viewLifecycleOwner, Observer { value ->
|
viewModel.scoreA.observe(viewLifecycleOwner) { value ->
|
||||||
updateScore(binding.inputTeamA, value)
|
updateScore(binding.inputTeamA, value)
|
||||||
})
|
}
|
||||||
|
|
||||||
viewModel.scoreB.observe(viewLifecycleOwner, Observer { value ->
|
viewModel.scoreB.observe(viewLifecycleOwner) { value ->
|
||||||
updateScore(binding.inputTeamB, value)
|
updateScore(binding.inputTeamB, value)
|
||||||
})
|
}
|
||||||
|
|
||||||
setListeners()
|
setListeners()
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
package me.zobrist.tichucounter.fragments
|
package me.zobrist.tichucounter.fragments
|
||||||
|
|
||||||
|
import SingleLiveEvent
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
class KeyboardViewModel: ViewModel() {
|
class KeyboardViewModel : ViewModel() {
|
||||||
private val _scoreA: MutableLiveData<Int?> = MutableLiveData<Int?>()
|
private val _scoreA: MutableLiveData<Int?> = MutableLiveData()
|
||||||
private val _scoreB: MutableLiveData<Int?> = MutableLiveData<Int?>()
|
private val _scoreB: MutableLiveData<Int?> = MutableLiveData()
|
||||||
private val _enableSubmitButton: MutableLiveData<Boolean> = MutableLiveData<Boolean>()
|
private val _enableSubmitButton: MutableLiveData<Boolean> = MutableLiveData()
|
||||||
private val _submitButtonClicked: MutableLiveData<Boolean> = MutableLiveData<Boolean>()
|
private val _submitButtonClicked: SingleLiveEvent<Boolean> = SingleLiveEvent()
|
||||||
|
|
||||||
val scoreA: LiveData<Int?>
|
val scoreA: LiveData<Int?>
|
||||||
get() {
|
get() {
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import android.util.Log
|
||||||
|
import androidx.annotation.MainThread
|
||||||
|
import androidx.lifecycle.LifecycleOwner
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A lifecycle-aware observable that sends only new updates after subscription, used for events like
|
||||||
|
* navigation and Snackbar messages.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This avoids a common problem with events: on configuration change (like rotation) an update
|
||||||
|
* can be emitted if the observer is active. This LiveData only calls the observable if there's an
|
||||||
|
* explicit call to setValue() or call().
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Note that only one observer is going to be notified of changes.
|
||||||
|
*/
|
||||||
|
class SingleLiveEvent<T> : MutableLiveData<T>() {
|
||||||
|
private val pending = AtomicBoolean(false)
|
||||||
|
|
||||||
|
@MainThread
|
||||||
|
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
|
||||||
|
if (hasActiveObservers()) {
|
||||||
|
Log.w(TAG, "Multiple observers registered but only one will be notified of changes.")
|
||||||
|
}
|
||||||
|
// Observe the internal MutableLiveData
|
||||||
|
super.observe(owner, Observer { t ->
|
||||||
|
if (pending.compareAndSet(true, false)) {
|
||||||
|
observer.onChanged(t)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainThread
|
||||||
|
override fun setValue(t: T?) {
|
||||||
|
pending.set(true)
|
||||||
|
super.setValue(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used for cases where T is Void, to make calls cleaner.
|
||||||
|
*/
|
||||||
|
@MainThread
|
||||||
|
fun call() {
|
||||||
|
value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val TAG = "SingleLiveEvent"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package me.zobrist.tichucounter.framework
|
|
||||||
|
|
||||||
import android.app.Application
|
|
||||||
import dagger.hilt.android.HiltAndroidApp
|
|
||||||
|
|
||||||
@HiltAndroidApp
|
|
||||||
class TichuCounterApplication : Application()
|
|
||||||
Reference in New Issue
Block a user