天天看點

Flutter實作倒計時功能

題記

—— 執劍天涯,從你的點滴積累開始,所及之處,必精益求精,即是折騰每一天。

本文是異步程式設計的定時器政策篇章,通過Timer來實作。

定時器的使用場景一般如下

  • 間隔一定的時間循環發起查詢
  • 倒計時

通過Timer實作間隔一定時間的循環執行

Timer的periodic函數開啟一個循環執行的任務,其參數一用來配制間隔執行這個任務的時間,參數二用來配置具體執行的任務,在使用時需要注意有建立就要有銷毀,以避免記憶體洩漏,如開啟一個間隔1秒的定時任務,如下代碼清單1-1所示:

class _FutureLoopTestPageState extends State {
  ///聲明變量
  Timer _timer;

  @override
  void initState() {
    super.initState();

    ///循環執行
    ///間隔1秒
    _timer = Timer.periodic(Duration(milliseconds: 1000), (timer) {
      ///定時任務
    });
  }

  @override
  void dispose() {
    ///取消計時器
    _timer.cancel();
    super.dispose();
  }
  ...
}           

實作一個APP啟動頁面的倒計時

如下圖所示為常見App的一個啟動頁面的倒計時顯示效果,對應代碼清單 1-3.

Flutter實作倒計時功能

對應的實作代碼如下:

///代碼清單 1-3 實作一個倒計時
class FutureLoopTestPage2 extends StatefulWidget {
  @override
  _FutureLoopTestPageState createState() => _FutureLoopTestPageState();
}

//lib/code/main_data.dart
class _FutureLoopTestPageState extends State<FutureLoopTestPage2> {
  ///聲明變量
  Timer _timer;
  ///記錄目前的時間
  int curentTimer = 0;

  @override
  void initState() {
    super.initState();

    ///循環執行
    ///間隔1秒
    _timer = Timer.periodic(Duration(milliseconds: 1000), (timer) {
      ///自增
      curentTimer++;
      ///到5秒後停止 
      if (curentTimer == 5) {
        _timer.cancel();
      }
      setState(() {});
    });
  }

  @override
  void dispose() {
    ///取消計時器
    _timer.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("倒計時"),
      ),
      backgroundColor: Colors.white,

      ///填充布局
      body: Container(
          padding: EdgeInsets.all(20),
          width: double.infinity,
          height: double.infinity,
          child: Column(
            children: [
              ///層疊布局将進度與文字疊在一起
              Stack(
                ///子Widget居中
                alignment: Alignment.center,
                children: [
                  ///圓形進度
                  CircularProgressIndicator(
                    ///目前訓示的進度 0.0 -1.0
                    value: curentTimer / 5,
                  ),
                  ///顯示的文本
                  Text("${5-curentTimer}"),
                ],
              )
            ],
          )),
    );
  }
}
           

在上述代碼清單 1-3 中所示的效果,圓形進度執行的有點死闆的效果,如下圖所示為優化後的效果,給人的視覺效果比較舒适,對應代碼清單1-4。

Flutter實作倒計時功能
///代碼清單 1-4 
class FutureLoopTestPage3 extends StatefulWidget {
  @override
  _FutureLoopTestPageState createState() => _FutureLoopTestPageState();
}

//lib/code/main_data.dart
class _FutureLoopTestPageState extends State<FutureLoopTestPage3> {
  ///聲明變量
  Timer _timer;
  ///記錄目前的時間
  int curentTimer = 0;

  @override
  void initState() {
    super.initState();

    ///循環執行
    ///間隔1秒
    _timer = Timer.periodic(Duration(milliseconds: 100), (timer) {
      ///自增
      curentTimer+=100;
      ///到5秒後停止
      if (curentTimer >= 5000) {
        _timer.cancel();
      }
      setState(() {});
    });
  }

  @override
  void dispose() {
    ///取消計時器
    _timer.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("倒計時"),
      ),
      backgroundColor: Colors.white,

      ///填充布局
      body: Container(
          padding: EdgeInsets.all(20),
          width: double.infinity,
          height: double.infinity,
          child: Column(
            children: [
              ///層疊布局将進度與文字疊在一起
              Stack(
                ///子Widget居中
                alignment: Alignment.center,
                children: [
                  ///圓形進度
                  CircularProgressIndicator(
                    ///目前訓示的進度 0.0 -1.0
                    value: curentTimer / 5000,
                  ),
                  ///顯示的文本
                  Text("${(curentTimer/1000).toInt()}"),
                ],
              )
            ],
          )),
    );
  }
}
           

代碼清單 1-3 與代碼 清單1-4中所示的效果有完全不同的視覺效果,在代碼實作的方式上隻是重新整理頻率的不一樣。

完畢

Flutter實作倒計時功能

繼續閱讀