Skip to content

[Flutter] 使用 Timer 模組實現倒數計時

Last Updated on 2021-05-18 by Clay

在開發各式各樣不同功能的 App 時,我們難免會有需要用到『計時』這項功能的時候;也許是在給予使用者時限、也許是在計算時機觸發事件、也或許是在實現一個基本的計時——在 Flutter 當中,我們通通可以使用 "Timer" 來實現這些功能。

以下,就簡單紀錄該怎麼使用 Timer。


Timer 的使用方法

首先,我們需要訂出我們『每隔多久呼叫一次 Timer 函式』:

var period = const Duration(seconds: 1);



像這樣,就是每隔『1 秒』便呼叫一次;如果設定成 5 ,那就是每隔 5 秒呼叫一次。

Timer.periodic(period, (timer) {
  // TODO

  setState(() {});
  });
}



然後我們便可以這樣使用 Timer —— 每隔一段時間就固定呼叫一次我們寫下的指令。當然,別忘了要設定結束條件,否則事件會一直進行下去。


程式碼

當然,了解 Timer 最快的方法莫過於直接看個範例:

import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: timerPage(),
    );
  }
}

class timerPage extends StatefulWidget {
  @override
  _timerPage createState() => _timerPage();
}

class _timerPage extends State<timerPage> {
  int time01 = 60;
  int time02 = 60;
  bool time01_start = false;
  bool time02_start = false;

  var period = const Duration(seconds: 1);

  void time01_button_event(){
    if (time01_start){
      time01_start = false;
    }
    else{
      time01_start = true;
    }

    Timer.periodic(period, (timer) {
      if (time01 < 1 || time01_start == false) {
        timer.cancel();
        timer = null;
      }
      else{
        time01--;
      }
      setState(() {});
    });
  }

  void time02_button_event(){
    if (time02_start){
      time02_start = false;
    }
    else{
      time02_start = true;
    }

    Timer.periodic(period, (timer) {
      if (time02 < 1 || time02_start == false) {
        timer.cancel();
        timer = null;
      }
      else{
        time02--;
      }
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('$time01', style: TextStyle(fontSize: 40)),
                  RaisedButton(
                    onPressed: () => time01_button_event(),
                    child: Text(time01_start?'PAUSE':'START'),
                  )
                ],
              ),
              Container(
                width: MediaQuery.of(context).size.width/5,
              ),
              Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text('$time02', style: TextStyle(fontSize: 40)),
                  RaisedButton(
                    onPressed: () => time02_button_event(),
                    child: Text(time02_start?'PAUSE':'START'),
                  )
                ],
              ),
            ],
          )
        )
    );
  }
}



Output:

兩邊的倒數計時都是異步處理的,相當方便。


BUG

當然,如果實際試用會發現,只要連點按鈕就會讓時間快速地減少:這很明顯不是我們想要的功能。

不過我目前研究這個是為了將過去寫的 App 使用 Flutter 再實現一遍。以我的狀況來講,我只要多設個判斷式就可以解決這個問題了。

希望大家都可以順利在 Flutter 中使用 Timer。

Tags:

Leave a Reply