Add animation to the timer screen
This commit is contained in:
parent
6fab0ff4f9
commit
26c6977fd6
8 changed files with 48 additions and 287 deletions
|
@ -1,139 +0,0 @@
|
||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<code_scheme name="Project" version="173">
|
|
||||||
<JetCodeStyleSettings>
|
|
||||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
|
||||||
<value>
|
|
||||||
<package name="java.util" alias="false" withSubpackages="false" />
|
|
||||||
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
|
||||||
<package name="io.ktor" alias="false" withSubpackages="true" />
|
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
|
||||||
<value>
|
|
||||||
<package name="" alias="false" withSubpackages="true" />
|
|
||||||
<package name="java" alias="false" withSubpackages="true" />
|
|
||||||
<package name="javax" alias="false" withSubpackages="true" />
|
|
||||||
<package name="kotlin" alias="false" withSubpackages="true" />
|
|
||||||
<package name="" alias="true" withSubpackages="true" />
|
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
|
||||||
</JetCodeStyleSettings>
|
|
||||||
<codeStyleSettings language="XML">
|
|
||||||
<indentOptions>
|
|
||||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
|
||||||
</indentOptions>
|
|
||||||
<arrangement>
|
|
||||||
<rules>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>xmlns:android</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>xmlns:.*</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
<order>BY_NAME</order>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*:id</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*:name</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>name</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>style</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
<order>BY_NAME</order>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
<order>BY_NAME</order>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
</rules>
|
|
||||||
</arrangement>
|
|
||||||
</codeStyleSettings>
|
|
||||||
<codeStyleSettings language="kotlin">
|
|
||||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
|
||||||
<option name="WRAP_ON_TYPING" value="1" />
|
|
||||||
</codeStyleSettings>
|
|
||||||
</code_scheme>
|
|
||||||
</component>
|
|
|
@ -1,123 +0,0 @@
|
||||||
<component name="ProjectCodeStyleConfiguration">
|
|
||||||
<code_scheme name="Project" version="173">
|
|
||||||
<JetCodeStyleSettings>
|
|
||||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
|
||||||
</JetCodeStyleSettings>
|
|
||||||
<codeStyleSettings language="XML">
|
|
||||||
<indentOptions>
|
|
||||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
|
||||||
</indentOptions>
|
|
||||||
<arrangement>
|
|
||||||
<rules>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>xmlns:android</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>xmlns:.*</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
<order>BY_NAME</order>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*:id</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*:name</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>name</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>style</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
<order>BY_NAME</order>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<rule>
|
|
||||||
<match>
|
|
||||||
<AND>
|
|
||||||
<NAME>.*</NAME>
|
|
||||||
<XML_ATTRIBUTE />
|
|
||||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
|
||||||
</AND>
|
|
||||||
</match>
|
|
||||||
<order>BY_NAME</order>
|
|
||||||
</rule>
|
|
||||||
</section>
|
|
||||||
</rules>
|
|
||||||
</arrangement>
|
|
||||||
</codeStyleSettings>
|
|
||||||
<codeStyleSettings language="kotlin">
|
|
||||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
|
||||||
<option name="WRAP_ON_TYPING" value="1" />
|
|
||||||
</codeStyleSettings>
|
|
||||||
</code_scheme>
|
|
||||||
</component>
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8 (5)" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|
|
@ -102,6 +102,8 @@ dependencies {
|
||||||
implementation "org.koin:koin-android:$koin_version"
|
implementation "org.koin:koin-android:$koin_version"
|
||||||
testImplementation "org.koin:koin-test:$koin_version"
|
testImplementation "org.koin:koin-test:$koin_version"
|
||||||
|
|
||||||
|
implementation 'com.robinhood.ticker:ticker:2.0.2'
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.wbrawner.trainterval.activetimer
|
package com.wbrawner.trainterval.activetimer
|
||||||
|
|
||||||
|
import android.animation.ArgbEvaluator
|
||||||
|
import android.animation.ValueAnimator
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.media.SoundPool
|
import android.media.SoundPool
|
||||||
|
@ -16,6 +18,7 @@ import androidx.fragment.app.activityViewModels
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import com.robinhood.ticker.TickerUtils
|
||||||
import com.google.android.gms.wearable.*
|
import com.google.android.gms.wearable.*
|
||||||
import com.wbrawner.trainterval.Logger
|
import com.wbrawner.trainterval.Logger
|
||||||
import com.wbrawner.trainterval.R
|
import com.wbrawner.trainterval.R
|
||||||
|
@ -89,6 +92,9 @@ class ActiveTimerFragment : Fragment(), MessageClient.OnMessageReceivedListener
|
||||||
it.setSupportActionBar(toolbar)
|
it.setSupportActionBar(toolbar)
|
||||||
it.supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
it.supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
}
|
}
|
||||||
|
timeRemaining.setCharacterLists(TickerUtils.provideNumberList() + ":")
|
||||||
|
timerSets.setCharacterLists(TickerUtils.provideNumberList())
|
||||||
|
timerRounds.setCharacterLists(TickerUtils.provideNumberList())
|
||||||
coroutineScope = CoroutineScope(Dispatchers.Main)
|
coroutineScope = CoroutineScope(Dispatchers.Main)
|
||||||
coroutineScope!!.launch {
|
coroutineScope!!.launch {
|
||||||
activeTimerViewModel.timerState.observe(viewLifecycleOwner, Observer { state ->
|
activeTimerViewModel.timerState.observe(viewLifecycleOwner, Observer { state ->
|
||||||
|
@ -131,7 +137,19 @@ class ActiveTimerFragment : Fragment(), MessageClient.OnMessageReceivedListener
|
||||||
}
|
}
|
||||||
(activity as? AppCompatActivity)?.supportActionBar?.title = state.timerName
|
(activity as? AppCompatActivity)?.supportActionBar?.title = state.timerName
|
||||||
val backgroundColor = resources.getColor(state.phase.colorRes, context?.theme)
|
val backgroundColor = resources.getColor(state.phase.colorRes, context?.theme)
|
||||||
timerBackground.setBackgroundColor(backgroundColor)
|
Log.d("ActiveTimerFragment", "State: $state")
|
||||||
|
state.previousPhase?.let {
|
||||||
|
val previousBackgroundColor = resources.getColor(it.colorRes, context?.theme)
|
||||||
|
val colorAnimation =
|
||||||
|
ValueAnimator.ofObject(ArgbEvaluator(), previousBackgroundColor, backgroundColor)
|
||||||
|
colorAnimation.duration = 250
|
||||||
|
colorAnimation.addUpdateListener { animator ->
|
||||||
|
timerBackground.setBackgroundColor(
|
||||||
|
animator.animatedValue as Int
|
||||||
|
)
|
||||||
|
}
|
||||||
|
colorAnimation.start()
|
||||||
|
} ?: timerBackground.setBackgroundColor(backgroundColor)
|
||||||
playPauseButton.setImageDrawable(
|
playPauseButton.setImageDrawable(
|
||||||
requireContext().getDrawable(
|
requireContext().getDrawable(
|
||||||
if (state.isRunning) R.drawable.ic_pause
|
if (state.isRunning) R.drawable.ic_pause
|
||||||
|
|
|
@ -39,7 +39,7 @@ class ActiveTimerViewModel : ViewModel() {
|
||||||
currentRound = timer.cycles
|
currentRound = timer.cycles
|
||||||
timeRemaining = timer.warmUpDuration
|
timeRemaining = timer.warmUpDuration
|
||||||
currentPhase = Phase.WARM_UP
|
currentPhase = Phase.WARM_UP
|
||||||
updateTimer()
|
updateTimer(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,34 +47,27 @@ class ActiveTimerViewModel : ViewModel() {
|
||||||
if (timerJob != null) {
|
if (timerJob != null) {
|
||||||
timerJob?.cancel()
|
timerJob?.cancel()
|
||||||
timerJob = null
|
timerJob = null
|
||||||
timerState.postValue(
|
updateTimer(null)
|
||||||
TimerRunningState(
|
|
||||||
timer,
|
|
||||||
timeRemaining,
|
|
||||||
currentSet,
|
|
||||||
currentRound,
|
|
||||||
currentPhase,
|
|
||||||
timerJob != null
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
startTimer()
|
startTimer(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startTimer() {
|
private fun startTimer(previousPhase: Phase?) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
timerJob = launch {
|
timerJob = launch {
|
||||||
updateTimer()
|
updateTimer(previousPhase)
|
||||||
while (coroutineContext.isActive && timerJob != null) {
|
while (coroutineContext.isActive && timerJob != null) {
|
||||||
delay(1_000)
|
delay(1_000)
|
||||||
timeRemaining -= 1_000
|
timeRemaining -= 1_000
|
||||||
|
// We need to recalculate the previous phase on each iteration
|
||||||
|
val previousPhaseOngoing = currentPhase
|
||||||
if (timeRemaining <= 0) {
|
if (timeRemaining <= 0) {
|
||||||
goForward()
|
goForward()
|
||||||
}
|
}
|
||||||
updateTimer()
|
updateTimer(if (previousPhaseOngoing != currentPhase) previousPhaseOngoing else null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,22 +75,24 @@ class ActiveTimerViewModel : ViewModel() {
|
||||||
|
|
||||||
fun skipAhead() {
|
fun skipAhead() {
|
||||||
timerJob?.cancel()
|
timerJob?.cancel()
|
||||||
|
var previousPhase: Phase? = null
|
||||||
when (currentPhase) {
|
when (currentPhase) {
|
||||||
Phase.COOL_DOWN -> {
|
Phase.COOL_DOWN -> {
|
||||||
timeRemaining = 0
|
timeRemaining = 0
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
previousPhase = currentPhase
|
||||||
goForward()
|
goForward()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (timerJob != null) {
|
if (timerJob != null) {
|
||||||
startTimer()
|
startTimer(previousPhase)
|
||||||
} else {
|
} else {
|
||||||
updateTimer()
|
updateTimer(previousPhase)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTimer() {
|
private fun updateTimer(previousPhase: Phase?) {
|
||||||
timerState.postValue(
|
timerState.postValue(
|
||||||
TimerRunningState(
|
TimerRunningState(
|
||||||
timer,
|
timer,
|
||||||
|
@ -105,6 +100,7 @@ class ActiveTimerViewModel : ViewModel() {
|
||||||
currentSet,
|
currentSet,
|
||||||
currentRound,
|
currentRound,
|
||||||
currentPhase,
|
currentPhase,
|
||||||
|
previousPhase,
|
||||||
timerJob != null
|
timerJob != null
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -154,6 +150,7 @@ class ActiveTimerViewModel : ViewModel() {
|
||||||
|
|
||||||
fun goBack() {
|
fun goBack() {
|
||||||
timerJob?.cancel()
|
timerJob?.cancel()
|
||||||
|
var previousPhase: Phase = currentPhase
|
||||||
when (currentPhase) {
|
when (currentPhase) {
|
||||||
Phase.WARM_UP -> {
|
Phase.WARM_UP -> {
|
||||||
timeRemaining = timer.warmUpDuration
|
timeRemaining = timer.warmUpDuration
|
||||||
|
@ -191,9 +188,9 @@ class ActiveTimerViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (timerJob != null) {
|
if (timerJob != null) {
|
||||||
startTimer()
|
startTimer(previousPhase)
|
||||||
} else {
|
} else {
|
||||||
updateTimer()
|
updateTimer(previousPhase)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||||
android:textColor="@color/colorOnSurface" />
|
android:textColor="@color/colorOnSurface" />
|
||||||
|
|
||||||
<TextView
|
<com.robinhood.ticker.TickerView
|
||||||
android:id="@+id/timerSets"
|
android:id="@+id/timerSets"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||||
android:textColor="@color/colorOnSurface" />
|
android:textColor="@color/colorOnSurface" />
|
||||||
|
|
||||||
<TextView
|
<com.robinhood.ticker.TickerView
|
||||||
android:id="@+id/timerRounds"
|
android:id="@+id/timerRounds"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
tools:text="Warm-Up" />
|
tools:text="Warm-Up" />
|
||||||
|
|
||||||
<TextView
|
<com.robinhood.ticker.TickerView
|
||||||
android:id="@+id/timeRemaining"
|
android:id="@+id/timeRemaining"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
|
@ -15,6 +15,7 @@ sealed class IntervalTimerState : Serializable {
|
||||||
val currentRound: Int,
|
val currentRound: Int,
|
||||||
val soundId: Int?,
|
val soundId: Int?,
|
||||||
val phase: Phase,
|
val phase: Phase,
|
||||||
|
val previousPhase: Phase?,
|
||||||
val isRunning: Boolean,
|
val isRunning: Boolean,
|
||||||
val vibrate: Boolean
|
val vibrate: Boolean
|
||||||
) : IntervalTimerState() {
|
) : IntervalTimerState() {
|
||||||
|
@ -24,10 +25,12 @@ sealed class IntervalTimerState : Serializable {
|
||||||
currentSet: Int,
|
currentSet: Int,
|
||||||
currentRound: Int,
|
currentRound: Int,
|
||||||
phase: Phase,
|
phase: Phase,
|
||||||
|
previousPhase: Phase?,
|
||||||
timerRunning: Boolean
|
timerRunning: Boolean
|
||||||
) : this(
|
) : this(
|
||||||
timerName = timer.name,
|
timerName = timer.name,
|
||||||
phase = phase,
|
phase = phase,
|
||||||
|
previousPhase = previousPhase,
|
||||||
timeRemaining = timeRemaining.toIntervalDuration().toString(),
|
timeRemaining = timeRemaining.toIntervalDuration().toString(),
|
||||||
currentSet = currentSet,
|
currentSet = currentSet,
|
||||||
currentRound = currentRound,
|
currentRound = currentRound,
|
||||||
|
@ -57,6 +60,7 @@ const val KEY_CURRENT_SET = "com.wbrawner.trainterval.currentSet"
|
||||||
const val KEY_CURRENT_ROUND = "com.wbrawner.trainterval.currentRound"
|
const val KEY_CURRENT_ROUND = "com.wbrawner.trainterval.currentRound"
|
||||||
const val KEY_SOUND_ID = "com.wbrawner.trainterval.soundId"
|
const val KEY_SOUND_ID = "com.wbrawner.trainterval.soundId"
|
||||||
const val KEY_PHASE = "com.wbrawner.trainterval.phase"
|
const val KEY_PHASE = "com.wbrawner.trainterval.phase"
|
||||||
|
const val KEY_PREVIOUS_PHASE = "com.wbrawner.trainterval.previousPhase"
|
||||||
const val KEY_RUNNING = "com.wbrawner.trainterval.timerRunning"
|
const val KEY_RUNNING = "com.wbrawner.trainterval.timerRunning"
|
||||||
const val KEY_VIBRATE = "com.wbrawner.trainterval.vibrate"
|
const val KEY_VIBRATE = "com.wbrawner.trainterval.vibrate"
|
||||||
|
|
||||||
|
@ -83,6 +87,7 @@ fun DataMap.toIntervalTimerState(): IntervalTimerState? = when (getString(KEY_ST
|
||||||
getInt(KEY_CURRENT_ROUND),
|
getInt(KEY_CURRENT_ROUND),
|
||||||
getInt(KEY_SOUND_ID),
|
getInt(KEY_SOUND_ID),
|
||||||
Phase.valueOf(getString(KEY_PHASE)),
|
Phase.valueOf(getString(KEY_PHASE)),
|
||||||
|
getString(KEY_PREVIOUS_PHASE)?.let { Phase.valueOf(it) },
|
||||||
getBoolean(KEY_RUNNING),
|
getBoolean(KEY_RUNNING),
|
||||||
getBoolean(KEY_VIBRATE)
|
getBoolean(KEY_VIBRATE)
|
||||||
)
|
)
|
||||||
|
@ -100,6 +105,7 @@ fun IntervalTimerState.TimerRunningState.toDataMap(): DataMap {
|
||||||
putInt(KEY_SOUND_ID, it)
|
putInt(KEY_SOUND_ID, it)
|
||||||
}
|
}
|
||||||
putString(KEY_PHASE, state.phase.name)
|
putString(KEY_PHASE, state.phase.name)
|
||||||
|
putString(KEY_PREVIOUS_PHASE, state.previousPhase?.name)
|
||||||
putBoolean(KEY_RUNNING, state.isRunning)
|
putBoolean(KEY_RUNNING, state.isRunning)
|
||||||
putBoolean(KEY_VIBRATE, state.vibrate)
|
putBoolean(KEY_VIBRATE, state.vibrate)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue