Flutter - 如何在 flutter 中创建 30 分钟或任何后台计时器?

问题描述 投票:0回答:2

大家好!

例如: 我希望当用户单击按钮时启动 30 分钟计时器并禁用按钮。如果用户关闭应用程序但计时器没有停止,它应该在后台工作,我该如何创建这个系统? 简单来说,我希望它像糖果粉碎一样,当生命为 0 时,然后在 1 小时生命满 5 后启动 1 小时的后台计时器...

我在 pub.dev 搜索,但找不到任何插件或包

flutter timer background-process countdowntimer
2个回答
1
投票

也许这对你有用这也会在应用程序在后台运行时运行

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Counter App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Counter App'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {

  AnimationController controller;

  Duration get duration => controller.duration * controller.value;

  bool get expired => duration.inSeconds == 0;

  @override
  void initState() {
    controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 30),
    );
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            AnimatedBuilder(
                animation: controller,
                builder: (BuildContext context, Widget child) {
                  return new Text(
                    '${duration.inSeconds}',
                    style: new TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 50.0,
                    ),
                  );
                }),
            new Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                new RaisedButton(
                  padding: const EdgeInsets.all(15.0),
                  textColor: Colors.white,
                  color: Colors.redAccent,
                  onPressed: () {
                    setState(() {
                      controller.reverse(from: 1);
                    });
                  },
                  child: new Text("Start"),
                ),
                new RaisedButton(
                  padding: const EdgeInsets.all(15.0),
                  textColor: Colors.white,
                  color: Colors.redAccent,
                  onPressed: () {
                    setState(() {
                      controller.reset();
                    });
                  },
                  child: new Text("Reset"),
                ),
              ],
            ),
          ],
        ),
      ), 
    );
  }
}

您可以查看此链接


0
投票

尝试这个方法,

TimerDifferenceHandler 类

当应用程序来自后台时,该类将处理当前时间和结束时间之间的时间差。

    class TimerDifferenceHandler {

      static late DateTime endingTime;
    
      static final TimerDifferenceHandler _instance = TimerDifferenceHandler();
    
      static TimerDifferenceHandler get instance => _instance;
    
      int get remainingSeconds {
        final DateTime dateTimeNow = DateTime.now();
        Duration remainingTime = endingTime.difference(dateTimeNow);
        // Return in seconds
        LoggerUtil.getInstance.print(
            "TimerDifferenceHandler  -remaining second = ${remainingTime.inSeconds}");
        return remainingTime.inSeconds;
      }
    
      void setEndingTime(int durationToEnd) {
        final DateTime dateTimeNow = DateTime.now();
        // Ending time is the current time plus the remaining duration.
        endingTime = dateTimeNow.add(
          Duration(
            seconds: durationToEnd,
          ),
        );
        LoggerUtil.getInstance.print("TimerDifferenceHandler  -setEndingTime = ${endingTime.toLocal().toString()}");
      }
    }

倒计时类

这将是处理所有计时器操作的基本帮助程序类。

class CountdownTimer {
  int _countdownSeconds;
  late Timer _timer;
  final Function(int)? _onTick;
  final Function()? _onFinished;
  final timerHandler = TimerDifferenceHandler.instance;
  bool onPausedCalled = false;

  CountdownTimer({
    required int seconds,
    Function(int)? onTick,
    Function()? onFinished,
  })  : _countdownSeconds = seconds,
        _onTick = onTick,
        _onFinished = onFinished;

  //this will start the timer
  void start() {
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      _countdownSeconds--;
      if (_onTick != null) {
        _onTick!(_countdownSeconds);
      }

      if (_countdownSeconds <= 0) {
        stop();
        if (_onFinished != null) {
          _onFinished!();
        }
      }
    });
  }


  //on pause current remaining time will be marked as end time in timerHandler class
  void pause(int endTime) {
    onPausedCalled = true;
    stop();
    timerHandler.setEndingTime(endTime); //setting end time
  }

  //on resume, the diff between current time and marked end time will be get from timerHandler class
  void resume() {
    if(!onPausedCalled){
      //if on pause not called, instead resumed will called directly.. so no need to do any operations
      return;
    }
    if (timerHandler.remainingSeconds > 0) {
      _countdownSeconds = timerHandler.remainingSeconds;
      start();
    } else {
      stop();
      _onTick!(_countdownSeconds); //callback
    }
    onPausedCalled = false;
  }

  void stop() {
    _timer.cancel();
    _countdownSeconds = 0;
  }
}

详细请参考这篇文章

https://navinkumar0118.medium.com/flutter-countdown-timer-works-in-background-f87488b0ba4c

© www.soinside.com 2019 - 2024. All rights reserved.