質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

2回答

728閲覧

順番にCountDownTimerを呼び出したいが、同時に動いてしまう。

satou_19

総合スコア4

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2020/09/07 05:54

編集2020/09/07 05:56

前提・実現したいこと

入力した時間分カウントダウンするタイマーアプリを作っているのですが、
同じCountDown関数を用いて「3.2.1」と、開始前のカウントダウンを表示した後に、
メインのカウントダウンを動かしたいです。

しかし現状は開始前のカウントダウンと、
メインのカウントダウンが同時に動いてしまうため困っています。

該当のソースコード

Kotlon

1package com.example.TapMeditation 2 3import androidx.appcompat.app.AppCompatActivity 4import android.os.Bundle 5import android.os.CountDownTimer 6import android.view.View 7import kotlinx.android.synthetic.main.activity_meditation.* 8 9class Meditation : AppCompatActivity() { 10 override fun onCreate(savedInstanceState: Bundle?) { 11 super.onCreate(savedInstanceState,) 12 setContentView(R.layout.activity_meditation,) 13 14 //問題の箇所、1行目と2行目が同時に動いてしまう。 15 //理想の動作としては1行目の終了後に、2行目を呼び出したい 16 CountDown(3000) 17 CountDown(intent.getLongExtra("TIME",0)) //他のアクティビティーから時間を受け取る 18 } 19 20 //カウントダウン開始関数 21 private lateinit var countDownTimer: CountDownTimer 22 fun CountDown(time:Long) { 23 24 countDownTimer = object : CountDownTimer(time, 500) { 25 override fun onTick(time: Long) { 26 val elapsedMinutes = time / 60000 27 val elapsedSeconds =(time-elapsedMinutes*60000)/1000 28 29 //カウントダウンをtxt_timeleftにて表示 30 txt_timeleft.text = String.format("%1$02d",elapsedMinutes)+":"+String.format("%1$02d",elapsedSeconds) 31 } 32 33 override fun onFinish() { 34 } 35 36 }.start() 37 } 38}

補足

・1行目、2行目を入れ替えると、
表示されるカウントダウンは変わるものの、同時にタイマーが動いている。

・エミュレーター上では、2行目のカウントダウン終了後に、
1行目のカウントダウンが残っていればそちらが表示される。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mikan_s4n

2020/09/08 05:19

callback処理は試されましたか?
guest

回答2

0

普通にcall backを受け取る方法でやってみました。

kotlin

1package com.example.TapMeditation 2 3import androidx.appcompat.app.AppCompatActivity 4import android.os.Bundle 5import android.os.CountDownTimer 6import android.view.View 7import kotlinx.android.synthetic.main.activity_meditation.* 8 9class Meditation : AppCompatActivity() { 10 override fun onCreate(savedInstanceState: Bundle?) { 11 super.onCreate(savedInstanceState,) 12 setContentView(R.layout.activity_meditation,) 13 14 CountDown(3000) { 15 CountDown(intent.getLongExtra("TIME", 0)) 16 } 17 } 18 19 //カウントダウン開始関数 20 private lateinit var countDownTimer: CountDownTimer 21 22 private fun CountDown(time:Long, onFinish : (() -> Unit)? = null) { 23 24 countDownTimer = object : CountDownTimer(time, 500) { 25 override fun onTick(time: Long) { 26 val elapsedMinutes = time / 60000 27 val elapsedSeconds =(time-elapsedMinutes*60000)/1000 28 29 //カウントダウンをtxt_timeleftにて表示 30 txt_timeleft.text = String.format("%1$02d",elapsedMinutes)+":"+String.format("%1$02d",elapsedSeconds) 31 } 32 33 override fun onFinish() { 34 onFinish() 35 } 36 37 }.start() 38 } 39}

投稿2020/09/09 05:03

編集2020/09/09 05:21
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

onCreate()に関数を並べただけでは、そのまま流れてしまうのですぐに後者が実行されてしまいます。前者が終了してから後者が実行されるような工夫が必要になります。

いろいろやり方はあるでしょうが、CountDown()を「カウントが終わるまで待たせる関数」に改良して、KotlinのCoroutineという非同期処理を用いて並べた2つのCountDown()関数を順番に実行してみてはどうでしょうか。

まずはCoroutineを用いるために、build.gradle(:app)のdependenciesブロックに1行追加してください。

gradle

1dependencies { 2 3 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7' 4 5}

一旦Syncしてから、Kotlinのコードを修正してください。

kotlin

1class Meditation : AppCompatActivity() { 2 private val scope = MainScope() 3 4 override fun onCreate(savedInstanceState: Bundle?) { 5 super.onCreate(savedInstanceState) 6 setContentView(R.layout.activity_meditation) 7 8 //問題の箇所、1行目と2行目が同時に動いてしまう。 9 //理想の動作としては1行目の終了後に、2行目を呼び出したい 10 11 // このlaunchのブロックの中がCoroutineとして実行される 12 scope.launch { 13 CountDown(3000) 14 CountDown(intent.getLongExtra("TIME", 0)) //他のアクティビティーから時間を受け取る 15 } 16 } 17 18 //カウントダウン開始関数 19 private lateinit var countDownTimer: CountDownTimer 20 21 // suspendを付加して「待たせる関数」であることを宣言する 22 private suspend fun CountDown(time: Long) = suspendCoroutine<Unit> { cont -> 23 24 countDownTimer = object : CountDownTimer(time, 500) { 25 override fun onTick(time: Long) { 26 val elapsedMinutes = time / 60000 27 val elapsedSeconds = (time - elapsedMinutes * 60000) / 1000 28 29 //カウントダウンをtxt_timeleftにて表示 30 //txt_timeleft.text = String.format("%1$02d",elapsedMinutes)+":"+String.format("%1$02d",elapsedSeconds) 31 val timeLeft = "%02d:%02d".format(elapsedMinutes, elapsedSeconds) // シンプルにしてみた 32 txt_timeleft.text = timeLeft 33 } 34 35 override fun onFinish() { 36 cont.resume(Unit) // suspend状態を解除する 37 } 38 }.start() 39 40 return@suspendCoroutine // resume()が呼ばれるまで待つ 41 } 42 43 override fun onDestroy() { 44 super.onDestroy() 45 // Activityが破棄されたときの後始末 46 if (::countDownTimer.isInitialized) { 47 countDownTimer.cancel() 48 } 49 scope.cancel() 50 } 51}

元々の構造をできるだけ活かしているので流れ自体は読みやすいのではと思いますが、launchやらsuspendCoroutineやらと見慣れない関数については、それぞれのキーワードで検索すれば情報は豊富にありますので、それを参考にされると良いでしょう。

投稿2020/09/08 08:25

編集2020/09/08 14:04
keicha_hrs

総合スコア6768

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

satou_19

2020/09/13 17:22

ご返信遅くなり申し訳ありません! 無事に解決致しました! わざわざコードまで書いて頂き、 ありがとうございます! コルーチンという処理について知ることができたので、 とても良い学びの機会になりました! ただ、コールバック処理といった基本的な処理について、 まだまだ理解が浅い部分があるため、 今後はもう少し基礎的な手法を学んでから質問したいと思います!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問