diff --git a/.idea/misc.xml b/.idea/misc.xml index 00a0882..b56467e 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,6 +3,7 @@ diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 5ad72cd..8e55831 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,6 +29,9 @@ android { kotlinOptions { jvmTarget = '1.8' } + buildFeatures { + viewBinding true + } } dependencies { diff --git a/app/src/main/java/iam/thevoid/epic/timeapp/MainActivity.kt b/app/src/main/java/iam/thevoid/epic/timeapp/MainActivity.kt index d08be6e..4b8215d 100644 --- a/app/src/main/java/iam/thevoid/epic/timeapp/MainActivity.kt +++ b/app/src/main/java/iam/thevoid/epic/timeapp/MainActivity.kt @@ -1,10 +1,17 @@ package iam.thevoid.epic.timeapp -import androidx.appcompat.app.AppCompatActivity +import android.annotation.SuppressLint import android.os.Bundle -import android.widget.Button -import android.widget.EditText -import android.widget.TextView +import android.text.format.DateUtils +import androidx.appcompat.app.AppCompatActivity +import iam.thevoid.epic.timeapp.databinding.ActivityMainBinding +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Observable +import io.reactivex.rxjava3.disposables.Disposable +import io.reactivex.rxjava3.schedulers.Schedulers +import java.text.SimpleDateFormat +import java.util.* +import java.util.concurrent.TimeUnit // Дан экран с готовой разметкой // Реализовать при помощи RxJava @@ -27,34 +34,129 @@ import android.widget.TextView // состояния паузы class MainActivity : AppCompatActivity() { - - // Часы: - private lateinit var clockText: TextView - - // Обратный отсчёт - private lateinit var countdownText: TextView - private lateinit var countdownSecondsEditText: EditText - private lateinit var countdownStartButton: Button - - // Секундомер - private lateinit var stopwatchText: TextView - private lateinit var stopwatchMillisText: TextView - private lateinit var stopwatchStartButton: EditText - private lateinit var stopwatchEndButton: EditText + private lateinit var binding: ActivityMainBinding + private var disposableCountdownTimer: Disposable? = null + private var disposableStopWatchClock: Disposable? = null + private var stopwatchClockState = StopwatchClockState.STOP + private var milSecShift = 5L + private var lastMilSec = 0L override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + binding = ActivityMainBinding.inflate(layoutInflater) + setContentView(binding.root) + setStopwatchClockBegin() + binding.countdownText.text = getTimeForCountdown(0L, 0L) + } - clockText = findViewById(R.id.clockText) + @SuppressLint("SetTextI18n") + override fun onStart() { + super.onStart() + // *************** Current Time Clock *************** + observableInterval().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) + .subscribe { binding.clockText.text = it } + // *************** CountDown Timer *************** + binding.countdownStartButton.setOnClickListener { + disposeCountdown() + val inputCountDownSeconds: Long = binding.countdownEditText + .text.toString().toLongOrNull() ?: 0L + disposableCountdownTimer = getTimerOfCountDown(inputCountDownSeconds) + .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) + .subscribe({item -> binding.countdownText.text = "[ $item ]"}, {}) + } + // *************** StopWatch Clock *************** + binding.stopwatchStartButton.setOnClickListener { + when (stopwatchClockState) { + StopwatchClockState.STOP -> { + stopwatchClockState = StopwatchClockState.RUN + binding.stopwatchStartButton.text = "Start" + binding.stopwatchEndButton.text = "Pause" + } + StopwatchClockState.PAUSE -> { + stopwatchClockState = StopwatchClockState.RUN + binding.stopwatchStartButton.text = "Start" + binding.stopwatchEndButton.text = "Pause" + } + StopwatchClockState.RUN -> { + lastMilSec = 0 + } + } + disposeStopWatchClock() + disposableStopWatchClock = getStopwatchTimer(lastMilSec) + .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) + .subscribe {item -> + binding.stopwatchText.text = item.first + binding.stopwatchMillisText.text = item.second + lastMilSec = item.third + } + } + binding.stopwatchEndButton.setOnClickListener { + disposeStopWatchClock() + when (stopwatchClockState) { + StopwatchClockState.RUN -> { + stopwatchClockState = StopwatchClockState.PAUSE + binding.stopwatchStartButton.text = "Resume" + binding.stopwatchEndButton.text = "Reset" + } + StopwatchClockState.PAUSE -> { + stopwatchClockState = StopwatchClockState.STOP + lastMilSec = 0 + binding.stopwatchStartButton.text = "Start" + binding.stopwatchEndButton.text = "Pause" + setStopwatchClockBegin() + } else -> {setStopwatchClockBegin()} + } + } + } - countdownText = findViewById(R.id.countdownText) - countdownSecondsEditText = findViewById(R.id.countdownEditText) - countdownStartButton = findViewById(R.id.countdownStartButton) + // *************** get current time from observable and format it *************** + private fun observableInterval(): Observable { + return Observable.interval(1000, TimeUnit.MILLISECONDS).map { + SimpleDateFormat("[ HH:mm:ss ]", Locale.GERMAN).format(Calendar.getInstance().time) + } + } - stopwatchText = findViewById(R.id.stopwatchText) - stopwatchMillisText = findViewById(R.id.stopwatchMillisText) - stopwatchStartButton = findViewById(R.id.stopwatchStartButton) - stopwatchEndButton = findViewById(R.id.stopwatchEndButton) + // *************** Time format for Timer Of CountDown *************** + private fun getTimeForCountdown(tmr: Long, v: Long): String { + return DateUtils.formatElapsedTime(tmr - v) } + + // *************** Timer Of CountDown *************** + private fun getTimerOfCountDown(timeBeforeStop: Long): Observable { + return Observable.interval(1000, TimeUnit.MILLISECONDS) + .takeWhile { it <= timeBeforeStop } + .map { time -> getTimeForCountdown(timeBeforeStop, time) } + } + + private fun disposeCountdown() { + disposableCountdownTimer?.dispose(); disposableCountdownTimer = null + } + + private fun disposeStopWatchClock() { + disposableStopWatchClock?.dispose(); disposableStopWatchClock = null + } + + // *************** StopWatch beginning state *************** + private fun setStopwatchClockBegin() { + val info = getStopwatchClockTime(0L) + binding.stopwatchText.text = info.first + binding.stopwatchMillisText.text = info.second + } + + // *************** Format Time for StopWatch Clock *************** + private fun getStopwatchClockTime(time: Long): Triple { + val part1 = String.format("[ %02d:%02d:%02d ]", TimeUnit.MILLISECONDS.toHours(time), + TimeUnit.MILLISECONDS.toMinutes(time) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(time)), + TimeUnit.MILLISECONDS.toSeconds(time) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(time))) + val part2 = String.format("[ %03d ]", time - TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(time))) + return Triple(part1, part2, time) + } + + private fun getStopwatchTimer(lastMilSec: Long): Observable> { + return Observable.interval(milSecShift, TimeUnit.MILLISECONDS) + .map { t -> getStopwatchClockTime(t * milSecShift + lastMilSec) } + } + + enum class StopwatchClockState { RUN, PAUSE, STOP } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 81ade1e..297cae4 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -7,7 +7,7 @@ android:orientation="vertical" tools:context=".MainActivity" tools:ignore="HardcodedText,LabelFor"> - + - + diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml deleted file mode 100644 index 203e219..0000000 --- a/app/src/main/res/values-night/themes.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index eebc2d0..e017b57 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,6 +1,6 @@ - \ No newline at end of file