Flutter-タイマーアプリケーションを作ってみる3

Flutter-タイマーアプリケーションを作ってみる2の続き。

詳細設計へ落とす。文字に落とすとこんな感じ。
アプリケーションにはGetXパッケージを使用してMVVM的に作っている。

トップ画面

表示用のデータ

TitleTable-id を「ID」TitleTable-sTitleを「タイトル名」、TitleTable-idに一致するTimeTable-titleidのiTimeの合計を「時間」とする。

上記データをデータベースから取得しViewModel内のList(リスト情報)で管理する。

表示内容

上記1リスト項目は、ViewModel-リスト情報の1データに対応ようにする。

  • タイトル
    ViewModel-リスト情報-タイトルを使用
  • 時間
    ViewModel-リスト情報-時間を「H:mm:ss」で表示。

アクション


  • TitleTableに1レコード追加するとともに、VM-リスト情報にも追加データに対応するデータを追加。
    ViewModel-リスト情報-IDをパラメータにタイマー編集画面にジャンプ(注)。

  • ViewModel-リスト情報-IDをパラメータにタイマー実行画面にジャンプ(注)。

  • ViewModel-リスト情報-IDをパラメータにタイマー編集画面にジャンプ(注)。
  • スワイプ後
    該当するTitleTableのレコードを削除。
    TitleTable-id=ViewModel-リスト情報-IDなTitleTableのレコードを削除。
    またVM-リスト情報の該当するデータも削除。

上の「パラメータに~画面にジャンプ」というのは、具体的には以下のソースのtoControlメソッドの様な内容のもの。

https://github.com/take4blue/stacktimers/blob/main/lib/view/viewcontrol.dart

別のViewを表示するのに、それに関連しているViewModelにパラメータ情報を渡して表示させるという感じのもの。

タイマー実行画面

ViewModel構築パラメータとしてTitleTable-idを受け取る。

表示用のデータ

  • タイトル
    TitleTable-idのsTitleを使用。
  • タイマー情報
    TitleTable-id=TimeTable-titleidのレコードをiNoの昇順で取得し、iTime、iAlarm、iColorを保持するListを構築。
  • 1秒の度
    円弧描画に必要とする、1秒→度の変換係数を保持。
    「360/(タイマー情報-iTimeの合計)」
  • タイマー動作情報
    Stopwatchで管理
    総合計時間、スタートした時間、オフセット時間、経過時間とViewに表示させるための経過時間。
    時間は100msを1として取り扱っている(単位時間)。この単位で画面の更新も行っている。

当初の予定では、タイマー経過を表すアニメーションに関する情報もこちらで保持しようと思ったのだけど、最終的にはアニメーション内の処理側で毎回計算させるようにしたのでこちらからは外した。

次にタイマーをStopwatchで実現しようとしたのだけど、AndroidのDozeに対応できていなかったので別途独自設計した。結局Doze対応はできなかったのだけど。

表示内容(タイマー部分)

外周の円弧は、設定されているタイマー情報を表し、内側の円弧は経過時間を表すようにしている。

描画用の角度計算

ViewModel-総合計時間から1単位時間の角度(*1)を計算。

次にタイマー情報-iTimeからリスト情報の各変位角度を求める。

開始角度はViewModel-タイマー情報[0]が 0。ViewModel-タイマー情報[1]以降のものは、それより前のタイ―マー情報の変位角度を合計したものを開始角度にする。

ないとは思うけど、累積誤差により最終タイマー情報の開始角度+変位角度が360を超える場合、360に納めるように変位角度を調整する。
最大リスト数は5ほどと予想しているので、それほど累積誤差が多くなるとは想定していない。

これをもとに、外周部と内周部の描画を行う。

外周部の描画

ViewModel-タイマー情報の開始角度、変位角度とiColorを背景色として円弧を描画する。

内周部の描画

開始角度は0、変位角度は経過時間*角度(*1)の円弧を描画する。
背景色は、経過時間未満の部分は該当するiColorの色とする。

iTime iColor
30
40
15
  • 経過時間15の場合
    開始角度0、変位角度63の赤の円弧を描画。
  • 経過時間35の場合
    開始角度0、変位角度127の赤の円弧を描画。
    開始角度127、変位角度21の青の円弧を描画。
  • 経過時間70の場合
    開始角度0、変位角度127の赤の円弧を描画。
    開始角度127、変位角度169の青の円弧を描画。
  • 経過時間80の場合
    開始角度0、変位角度127の赤の円弧を描画。
    開始角度127、変位角度169の青の円弧を描画。
    開始角度296、変位角度21の緑の円弧を描画。

残時間表示

  • Lap
    現在のタイマー範囲でのタイマー時間に至るまでの残時間を表示する。
  • Total
    合計時間に至るまでの残時間を表示する。

アクション

  • 経過時間でのイベント処理
    100ms単位にイベントを発生し、タイマー部、残時間の表示を更新する。
  • skip_previous
    経過時間が現在のタイマー時間+1秒以上の時間の場合、時間経過を現在のタイマー時間の先頭に戻す。
    経過時間が現在のタイマー時間+1秒未満の場合、ひとつ前のタイマー時間の先頭に戻す。
    iNoが0のタイマー時間の場合、経過時間を0にする。
  • skip_next
    経過時間を、次のタイマー時間の先頭に経過時間を進める。
  • pause
    タイマーイベントの登録を解除し、時間経過を止める。
    またpauseボタンの代わりにplay_arrowボタンを表示する。
  • play_arrow
    タイマーイベントを登録し時間経過を進める。
    またplay_arrowボタンの代わりにpauseボタンを表示する。
  • 戻る
    トップ画面に戻る。

タイマー編集画面

ViewModel構築パラメータとしてTitleTable-idを受け取る。

表示用のデータ

  • タイトル
    TitleTable-idのsTitleを使用。
  • リスト表示情報
    TitleTable-id=TimeTable-titleidのレコードをiNoの昇順で取得し、id、iTime、iAlarm、iDuration、iColorを保持するListを構築。
    idはトップ画面に戻る際にTimeTableを更新するためのもの。
    タイマー編集画面内で追加された項目はidを-1としておく。
  • 削除id
    削除したデータのリスト表示情報-idが0以上の場合、保持する。

表示内容

 

上記1リスト項目は、ViewModel-リスト表示情報の1項目に該当する。

  • ??:??
    リスト表示情報-iTimeの内容を「m:ss」で表示。タップ可能とする。

  • リスト表示情報-iColorを背景色でタップ可能な四角形を表示。

  • タップ可能なedit_notificationsアイコンを表示。
  • ??
    リスト表示情報-iDuration(単位はミリ秒)の内容を秒に変換し「0.0」の形式で表示。タップ可能とする。

  • ReorderableListViewと連携したドラッグ可能位置を表すdrag_handleを表示。

  • Total
    リスト表示情報-iTimeの合計を「H:mm:ss」で表示する。

アクション

  • ??:?? タップ
    4ケタ個別に数値設定可能なドラムロールダイアログを表示。
    1桁目0-9、2桁目0-9、3桁目0-5、4桁目0-9。
    初期位置は現在設定されているViewModel-リスト表示情報-iTimeを「mm:ss」にフォーマットした情報をもとに決定する。
    また選択内容を「分:秒」から単位時間を算出しViewModel-リスト表示情報-iTimeに設定する。
  •  タップ
    色ピッカーダイアログを表示する。
    初期色はViewModel-リスト表示情報-iColorを使用する。
    設定時に選択内容をViewModel-リスト表示情報-iColorに設定する。
  • ?.? タップ
    音色(iAlarm)と発音期間(iDuration)を設定可能なドラムロールダイアログを表示。
    音色はAndroidSoundIDs class – flutter_beep library – Dart API (pub.dev)を文字列化したものをドラムロールに表示する。
    発音期間は、0.1秒から0.1秒単位で5.0秒まで指定可能とする。
  • タップ
    ViewModel-リスト表示情報の最終にデータを追加する。
    id:-1、iTime:0、iDuration:5003000、iColor:別記、iAlarm:0
  • 戻る
    ViewModelの内容でTitleTable、TimeTableを更新する。
    ViewModel-タイトルでTitleTable-sTitleを更新。
    ViewModel-削除idでTimeTable-idを持つレコードを削除。
    ViewModel-リスト表示情報-idが-1のものはTimeTableにレコードを追加。
    ViewModel-リスト表示情報-idが0以上のものは、その内容でTimeTableを更新。
    最後にトップ画面に戻る。

iColorの初期値

テーブルの番号(もしくはiNo)を7で割った余りの数値により、初期値を以下の様に定める。

余り
0 #22B14C(緑)
1 #FFF200(黄)
2 #FF7F27(オレンジ)
3 #99D9EA(薄いターコイズ)
4 #7092BE(ブルーグレー)
5 #C8BFE7(ラベンダー)
6 #C3C3C3(淡い灰色)

 

コメント

タイトルとURLをコピーしました