From 9382fce93d975349f437f47ab9333c1757dbd2a2 Mon Sep 17 00:00:00 2001 From: gleb molotkov Date: Sun, 17 Apr 2022 13:31:04 +0300 Subject: [PATCH 1/6] 1ver --- .idea/misc.xml | 1 + .idea/vcs.xml | 6 + app/build.gradle | 9 + .../iam/thevoid/epic/timeapp/MainActivity.kt | 187 +++++++++++++++++- app/src/main/res/layout/activity_main.xml | 7 +- app/src/main/res/values/strings.xml | 2 + 6 files changed, 201 insertions(+), 11 deletions(-) create mode 100644 .idea/vcs.xml diff --git a/.idea/misc.xml b/.idea/misc.xml index 00a0882..909d572 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..436c96f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,6 +33,14 @@ android { dependencies { + implementation 'com.jakewharton.rxbinding3:rxbinding:3.0.0-alpha2' + implementation 'com.jakewharton.rxrelay2:rxrelay:2.1.0' + implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0-rc01' + //implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0' + //implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' + implementation "io.reactivex.rxjava2:rxkotlin:2.4.0" + // implementation "io.reactivex.rxjava2:rxandroid:2.0.2" + // implementation "io.reactivex.rxjava3:rxjava:3.1.3" implementation 'io.reactivex.rxjava3:rxandroid:3.0.0' @@ -43,4 +51,5 @@ dependencies { testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + } \ No newline at end of file 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..dda654a 100644 --- a/app/src/main/java/iam/thevoid/epic/timeapp/MainActivity.kt +++ b/app/src/main/java/iam/thevoid/epic/timeapp/MainActivity.kt @@ -1,21 +1,42 @@ package iam.thevoid.epic.timeapp -import androidx.appcompat.app.AppCompatActivity +//import io.reactivex.rxjava3.core.Observable +// +// +import android.graphics.Color import android.os.Bundle import android.widget.Button import android.widget.EditText import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import com.jakewharton.rxbinding3.view.clicks +import io.reactivex.Observable +import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers +import io.reactivex.rxjava3.core.Flowable +import io.reactivex.rxkotlin.merge +import java.text.SimpleDateFormat +import java.util.* +import java.util.concurrent.Flow + +//import kotlinx.android.synthetic.main.activity_main.* +//import java.util.concurrent.TimeUnit +// + + +//import io.reactivex.android.schedulers.AndroidSchedulers +//import kotlinx.android.synthetic.main.activity_main.* +//import java.util.concurrent.TimeUnit // Дан экран с готовой разметкой // Реализовать при помощи RxJava // 1) Отображение часов,начинают работать при старте, показывают время в любом удобном формате. // Как пример можно использовать формат из разметки -// 2) Таймер +// 2) Таймер - ^? // а) Пользователь вводит количество секунд в поле // б) По нажатию на "Старт" начинается обратный отсчёт // в) (не обязательно) По окончании таймер каким либо образом сигнализирует об окончании, // например область таймера вспыхивает ярким цветом -// 3) Секундомер +// 3) Секундомер ^? - Не до конца доделал // а) Пользователь нажимает на "Старт", начинается отсчёт времени. В соответствующие текстовые // поля выводится количество прошедшего времени (отдельно время с точностью до секунд, // отдельно миллисекунды) @@ -25,6 +46,8 @@ import android.widget.TextView // отсчёт // г) (не обязательно) Можно сделать изменение состояние кнопки "Старт" на "Продолжить" для // состояния паузы +private const val MAXIMUM_STOP_WATCH_LIMIT = 36000000L +private const val NUMBER_OF_SECONDS_IN_ONE_MINUTE = 60 class MainActivity : AppCompatActivity() { @@ -39,22 +62,170 @@ class MainActivity : AppCompatActivity() { // Секундомер private lateinit var stopwatchText: TextView private lateinit var stopwatchMillisText: TextView - private lateinit var stopwatchStartButton: EditText - private lateinit var stopwatchEndButton: EditText + private lateinit var SecName: TextView + private lateinit var stopwatchStartButton: Button /*EditText*/ + private lateinit var stopwatchEndButton: Button /*EditText*/ + + + private val disposable = + io.reactivex.disposables.CompositeDisposable() + private val disposableMS = io.reactivex.disposables.CompositeDisposable() + //var disposable: Disposable? = null; + private val displayInitialState by lazy { resources.getString(R.string._0_0) } + private val displayInitialStateMS by lazy { resources.getString(R.string._0_0_0) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) clockText = findViewById(R.id.clockText) + clock() countdownText = findViewById(R.id.countdownText) countdownSecondsEditText = findViewById(R.id.countdownEditText) countdownStartButton = findViewById(R.id.countdownStartButton) + countdownStartButton.setOnClickListener { + // countdownText.text = "Hello Kitty!" + //backCount(countdownSecondsEditText.toString().toLong()) + timer(countdownSecondsEditText.text.toString().toLong()) + } + + stopwatchText = findViewById(R.id.stopwatchText) + stopwatchMillisText = findViewById(R.id.stopwatchMillisText) - stopwatchStartButton = findViewById(R.id.stopwatchStartButton) - stopwatchEndButton = findViewById(R.id.stopwatchEndButton) + // + SecName = findViewById(R.id.SecName) + // + + stopwatchStartButton = findViewById(R.id.stopwatchStartButton) + stopwatchEndButton = findViewById(R.id.stopwatchEndButton) + + + + + + + mergeClicks().switchMap { + if (it) timerObservable() + else Observable.just(displayInitialState) + }.subscribe(stopwatchText::setText) + .let(disposable::add) + + /* mergeClicks().switchMap { + if (it) timerObservableMS() + else Observable.just(displayInitialStateMS) + }.subscribe(/*stopwatchMillisText*/SecName::setText) + .let(disposableMS::add) + */ + + + + + } + + override fun onDestroy() { + disposable.clear() + disposableMS.clear() + super.onDestroy() } -} \ No newline at end of file + + private fun mergeClicks(): Observable = + listOf( stopwatchStartButton.clicks().map { true }, stopwatchEndButton.clicks().map { false }) + .merge() + .doOnNext(::buttonStateManager) + + private fun buttonStateManager(boolean: Boolean) { + stopwatchStartButton.isEnabled = !boolean + stopwatchEndButton.isEnabled = boolean + } + private fun timerObservable(): Observable = + Observable.interval(0, 1, java.util.concurrent.TimeUnit.SECONDS) + .takeWhile { it <= MAXIMUM_STOP_WATCH_LIMIT } + .map(timeFormatter) + .observeOn(io.reactivex.android.schedulers.AndroidSchedulers.mainThread()) + .doOnComplete { buttonStateManager(false) } + + private fun timerObservableMS(): Observable = + Observable.interval(0, 1, java.util.concurrent.TimeUnit.MILLISECONDS) + .takeWhile { it <= MAXIMUM_STOP_WATCH_LIMIT } + .map(timeFormatterMS) + .observeOn(io.reactivex.android.schedulers.AndroidSchedulers.mainThread()) + .doOnComplete { buttonStateManager(false) } + + private val timeFormatter: (Long) -> String = + { secs -> + if (secs == MAXIMUM_STOP_WATCH_LIMIT) displayInitialState + else "${secs / NUMBER_OF_SECONDS_IN_ONE_MINUTE} : ${secs % NUMBER_OF_SECONDS_IN_ONE_MINUTE}" + } + + + private val timeFormatterMS: (Long) -> String = + { secs -> + + if (secs == MAXIMUM_STOP_WATCH_LIMIT) displayInitialStateMS + else "${secs} " + } + + override fun onStop() { + super.onStop() + disposable?.dispose() + // disposable = null + } + + override fun onStart() { + super.onStart() + // disposable = null; // subscribeInput() + } + + val mSubscription: Flow.Subscription? = null + private fun timer(count: Long) { + if (count.toString().isEmpty()) + { countdownText.text = "err:" //+ count.toString() + + return} + Flowable.interval (0, 1, java.util.concurrent.TimeUnit.SECONDS) + .onBackpressureBuffer () + .take (count + 1) + .map{ aLong -> + count - aLong // + } + .observeOn (AndroidSchedulers.mainThread ()) + .subscribe({ + countdownText.text = it.toString() + if (it == 0L) { + countdownText.setTextColor(Color.RED) + } + }) + + + + } + + + private fun clock() { + val count: Long = 10000000000000000L + Flowable.interval (0, 1, java.util.concurrent.TimeUnit.SECONDS) + .onBackpressureBuffer () + .take (count + 1) + .map{ aLong -> + count - aLong // + } + .observeOn (AndroidSchedulers.mainThread ()) + .subscribe({ + //val curTime: Long = Date().getTime() + val currentTime = System.currentTimeMillis() + val simpleDateFormat = SimpleDateFormat(/*"hh:mm:ss.S"*/"HH:mm:ss.SSS") + val date = Date(currentTime) + val time: String = simpleDateFormat.format(date) + clockText.text = time + + }) + + + + } + + } + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 81ade1e..9d39399 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -59,12 +59,12 @@ tools:text="[02:37]" />