Skip to content
This repository has been archived by the owner. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
}
}

dependencies {
Expand Down
154 changes: 128 additions & 26 deletions app/src/main/java/iam/thevoid/epic/timeapp/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<String> {
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<String> {
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<String, String, Long> {
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<Triple<String, String, Long>> {
return Observable.interval(milSecShift, TimeUnit.MILLISECONDS)
.map { t -> getStopwatchClockTime(t * milSecShift + lastMilSec) }
}

enum class StopwatchClockState { RUN, PAUSE, STOP }
}
10 changes: 8 additions & 2 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
android:orientation="vertical"
tools:context=".MainActivity"
tools:ignore="HardcodedText,LabelFor">

<!--real time clock-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">

<TextView
style="@style/TitleText"
android:textSize="20sp"
android:text="Часы:" />

<TextView
Expand All @@ -28,14 +29,15 @@
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#ccc" />

<!--countdown timer-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">

<TextView
style="@style/TitleText"
android:textSize="20sp"
android:text="Обратный отсчёт:" />

<com.google.android.material.textfield.TextInputLayout
Expand All @@ -62,6 +64,7 @@
android:layout_marginStart="16dp"
android:layout_marginBottom="4dp"
android:layout_gravity="bottom"
android:elevation="5dp"
android:id="@+id/countdownStartButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
Expand All @@ -80,6 +83,7 @@

<TextView
style="@style/TitleText"
android:textSize="20sp"
android:text="Секундомер:" />

<androidx.constraintlayout.widget.ConstraintLayout
Expand Down Expand Up @@ -123,6 +127,7 @@
android:id="@+id/stopwatchStartButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="4dp"
android:text="Start" />

<View
Expand All @@ -134,6 +139,7 @@
android:id="@+id/stopwatchEndButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="4dp"
android:text="Pause" />
</LinearLayout>
</FrameLayout>
Expand Down
16 changes: 0 additions & 16 deletions app/src/main/res/values-night/themes.xml

This file was deleted.

4 changes: 2 additions & 2 deletions app/src/main/res/values/themes.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.MyApplication" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<style name="Theme.MyApplication" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
Expand All @@ -10,7 +10,7 @@
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<item name="android:statusBarColor" tools:targetApi="l">#45000000</item>
<!-- Customize your theme here. -->
</style>
</resources>