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 javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
private var updateOnChange: Boolean = true
|
||||
|
||||
@Inject
|
||||
lateinit var history: History
|
||||
private var currentRound: Round = Round(null, null)
|
||||
|
||||
private val keyboardViewModel: KeyboardViewModel by viewModels()
|
||||
@@ -58,7 +53,6 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
val json = this.getSharedPreferences("Settings", MODE_PRIVATE)
|
||||
.getString("history", "{\"scores\":[]}")
|
||||
history = Gson().fromJson(json, History::class.java)
|
||||
binding.contentMain.nameTeamA.setText(
|
||||
this.getSharedPreferences("Settings", MODE_PRIVATE).getString("nameTeamA", "TeamA")
|
||||
)
|
||||
@@ -66,7 +60,7 @@ class MainActivity : AppCompatActivity() {
|
||||
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 oldValue = currentRound.scoreA
|
||||
@@ -83,9 +77,9 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
keyboardViewModel.setSubmitButtonEnable(tichu.isValidRound(currentRound))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
keyboardViewModel.scoreB.observe(this, androidx.lifecycle.Observer { value ->
|
||||
keyboardViewModel.scoreB.observe(this) { value ->
|
||||
val tichu = Tichu()
|
||||
|
||||
val oldValue = currentRound.scoreB
|
||||
@@ -102,28 +96,27 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
keyboardViewModel.setSubmitButtonEnable(tichu.isValidRound(currentRound))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
keyboardViewModel.submitButtonClicked.observe(this, androidx.lifecycle.Observer {
|
||||
keyboardViewModel.submitButtonClicked.observe(this) {
|
||||
historyListViewModel.logRound(currentRound)
|
||||
keyboardViewModel.setScoreA(null)
|
||||
keyboardViewModel.setScoreB(null)
|
||||
})
|
||||
}
|
||||
|
||||
historyListViewModel.totalScoreA.observe(this, androidx.lifecycle.Observer { value ->
|
||||
historyListViewModel.totalScoreA.observe(this) { value ->
|
||||
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()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
|
||||
val prefs = this.getSharedPreferences("Settings", MODE_PRIVATE).edit()
|
||||
prefs.putString("history", Gson().toJson(history))
|
||||
prefs.putString("nameTeamA", binding.contentMain.nameTeamA.text.toString())
|
||||
prefs.putString("nameTeamB", binding.contentMain.nameTeamB.text.toString())
|
||||
prefs.apply()
|
||||
@@ -177,8 +170,7 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private fun clearAll() {
|
||||
|
||||
history.clearAll()
|
||||
historyListViewModel.clearAll()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
package me.zobrist.tichucounter.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.Fragment
|
||||
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.FragmentKeyboardBinding
|
||||
|
||||
class HistoryList : Fragment() {
|
||||
|
||||
@@ -46,13 +39,17 @@ class HistoryList : Fragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
|
||||
viewModel.historyA.observe(viewLifecycleOwner, Observer { text ->
|
||||
viewModel.historyA.observe(viewLifecycleOwner) { text ->
|
||||
binding.historyA.text = text
|
||||
})
|
||||
}
|
||||
|
||||
viewModel.historyB.observe(viewLifecycleOwner, Observer { text ->
|
||||
viewModel.historyB.observe(viewLifecycleOwner) { 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
|
||||
|
||||
import SingleLiveEvent
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
@@ -13,6 +14,7 @@ class HistoryListViewModel : ViewModel() {
|
||||
private val _totalScoreB: MutableLiveData<Int> = MutableLiveData<Int>()
|
||||
private val _historyA: 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
|
||||
}
|
||||
|
||||
val scrollDown: LiveData<Boolean>
|
||||
get() {
|
||||
return _scrollDown
|
||||
}
|
||||
|
||||
private fun getScoreA() {
|
||||
var tempScore = 0
|
||||
scores.forEach {
|
||||
@@ -68,33 +75,33 @@ class HistoryListViewModel : ViewModel() {
|
||||
_historyB.value = tempHistory
|
||||
}
|
||||
|
||||
fun logRound(round: Round) {
|
||||
scores.add(round.copy())
|
||||
private fun updateAll() {
|
||||
getHistoryA()
|
||||
getHistoryB()
|
||||
getScoreA()
|
||||
getScoreB()
|
||||
scrollDown()
|
||||
}
|
||||
|
||||
fun logRound(round: Round) {
|
||||
scores.add(round.copy())
|
||||
updateAll()
|
||||
}
|
||||
|
||||
fun revertLastRound() {
|
||||
if (scores.isNotEmpty()) {
|
||||
scores.removeAt(scores.size - 1)
|
||||
}
|
||||
getHistoryA()
|
||||
getHistoryB()
|
||||
getScoreA()
|
||||
getScoreB()
|
||||
updateAll()
|
||||
}
|
||||
|
||||
private fun scrollDown() {
|
||||
_scrollDown.value = true
|
||||
}
|
||||
|
||||
fun clearAll() {
|
||||
scores.clear()
|
||||
}
|
||||
|
||||
fun isEmpty(): Boolean {
|
||||
return scores.isEmpty()
|
||||
}
|
||||
|
||||
|
||||
|
||||
updateAll()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import android.widget.EditText
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import me.zobrist.tichucounter.databinding.FragmentKeyboardBinding
|
||||
|
||||
class Keyboard : Fragment() {
|
||||
@@ -56,13 +55,13 @@ class Keyboard : Fragment() {
|
||||
if (enabled) enableSubmitButton() else disableSubmitButton()
|
||||
})
|
||||
|
||||
viewModel.scoreA.observe(viewLifecycleOwner, Observer { value ->
|
||||
viewModel.scoreA.observe(viewLifecycleOwner) { value ->
|
||||
updateScore(binding.inputTeamA, value)
|
||||
})
|
||||
}
|
||||
|
||||
viewModel.scoreB.observe(viewLifecycleOwner, Observer { value ->
|
||||
viewModel.scoreB.observe(viewLifecycleOwner) { value ->
|
||||
updateScore(binding.inputTeamB, value)
|
||||
})
|
||||
}
|
||||
|
||||
setListeners()
|
||||
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
package me.zobrist.tichucounter.fragments
|
||||
|
||||
import SingleLiveEvent
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeyboardViewModel : ViewModel() {
|
||||
private val _scoreA: MutableLiveData<Int?> = MutableLiveData<Int?>()
|
||||
private val _scoreB: MutableLiveData<Int?> = MutableLiveData<Int?>()
|
||||
private val _enableSubmitButton: MutableLiveData<Boolean> = MutableLiveData<Boolean>()
|
||||
private val _submitButtonClicked: MutableLiveData<Boolean> = MutableLiveData<Boolean>()
|
||||
private val _scoreA: MutableLiveData<Int?> = MutableLiveData()
|
||||
private val _scoreB: MutableLiveData<Int?> = MutableLiveData()
|
||||
private val _enableSubmitButton: MutableLiveData<Boolean> = MutableLiveData()
|
||||
private val _submitButtonClicked: SingleLiveEvent<Boolean> = SingleLiveEvent()
|
||||
|
||||
val scoreA: LiveData<Int?>
|
||||
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