Flutter stopwatch not running anymore

Viewed 60

I am a beginner to flutter. I successfully created a stopwatch but once I updated flutter it stopped working entirely. It won't start or stop anymore. When running the code the stopwatch does not display the count up of numbers while still running fine behind the scenes. Does any know how to fix this, is my code now invalid, or do I need to add sometime new to make it work again? I will paste my code below, the first is the button to start the stopwatch and the second is my actual stopwatch code please let me know if you can help or need any more information.

child: GridView.count(
                primary: false,
                padding: const EdgeInsets.all(20),
                crossAxisSpacing: 10,
                mainAxisSpacing: 10,
                crossAxisCount: 3,
                children: widget.tasks.map((element) {
                  final isActive = activeTask != null && activeTask == element;
                  return GestureDetector(
                    onTap: () {
                      // set active task or toggle is active
                      if (isActive) {
                        setState(() {
                          activeTask = null;
                          StudyViewModel.stopwatch.start();
                          disable = true;
                        });
                      } else {
                        setState(() {
                          activeTask = element;
                          StudyViewModel.stopwatch.stop();
                          disable = false;
                        });
                      }
                    },
                    child: Container(
                      color: isActive ? Colors.amber : Colors.green,
                      padding: EdgeInsets.all(8),
                      child: Center(
                        child: Text(
                          element.name,
                          style: TextStyle(color: Colors.white, fontSize: 25),
                          textAlign: TextAlign.center,
                        ),
                      ),
                    ),
                  );
                }).toList(),

study_viewmodel.dart

import 'dart:convert';
import 'dart:async' show Future;
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:timestudyapp/models/elapsed_time.dart';
import 'package:timestudyapp/models/study.dart';
import 'package:path_provider/path_provider.dart';

class StudyViewModel {
  static List<Study> studies = [];
  static List<ValueChanged<ElapsedTime>> timerListeners =
      <ValueChanged<ElapsedTime>>[];
  static Stopwatch stopwatch = new Stopwatch();

  /// load from file...
  static Future load() async {
    try {
      File file = await getFile();
      String studiesJson = await file.readAsString();
      if (studiesJson.isNotEmpty) {
        List studiesParsed = json.decode(studiesJson);
        studies = studiesParsed.map((i) => Study.fromJson(i)).toList();
      }
    } catch (e) {
      print(e);
    }
  }

  static Future<File> getFile() async {
    final directory = await getApplicationDocumentsDirectory();
    final path = directory.path;
    return File('$path/studies.json');
  }

  static Future saveFile() async {
    File file = await getFile();
    file.writeAsString(json.encode(studies));
  }

  static bool checkName(String name) {
    bool match = false;
    for (int i = 0; i < studies.length; i++) {
      if (studies[i].name == name) {
        match = true;
        break;
      }
    }
    return match;
  }

  static String milliToElapsedString(int milliseconds) {
    final int hundreds = (milliseconds / 10).truncate();
    final int seconds = (hundreds / 100).truncate();
    final int minutes = (seconds / 60).truncate();
    String hundredsStr = (hundreds % 100).toString().padLeft(2, '0');
    String minutesStr = (minutes % 60).toString().padLeft(2, '0');
    String secondsStr = (seconds % 60).toString().padLeft(2, '0');
    return minutesStr + ':' + secondsStr + ':' + hundredsStr;
  }
}

timer_text.dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:timestudyapp/models/elapsed_time.dart';
import 'package:timestudyapp/viewmodels/study_viewmodel.dart';
import 'package:timestudyapp/widgets/hundreds.dart';
import 'package:timestudyapp/widgets/minutes_seconds.dart';

class TimerText extends StatefulWidget {
  final double fontSize;

  TimerText({required this.fontSize});

  TimerTextState createState() => new TimerTextState();
}

class TimerTextState extends State<TimerText> {
  late Timer timer;
  late int milliseconds;

  @override
  void initState() {
    timer = new Timer.periodic(Duration(milliseconds: 30), callback);
    super.initState();
  }

  @override
  void dispose() {
    timer.cancel();
    super.dispose();
  }

  void callback(Timer timer) {
    if (milliseconds != StudyViewModel.stopwatch.elapsedMilliseconds) {
      milliseconds = StudyViewModel.stopwatch.elapsedMilliseconds;
      final int hundreds = (milliseconds / 10).truncate();
      final int seconds = (hundreds / 100).truncate();
      final int minutes = (seconds / 60).truncate();
      final ElapsedTime elapsedTime = new ElapsedTime(
        hundreds: hundreds,
        seconds: seconds,
        minutes: minutes,
      );
      for (final listener in StudyViewModel.timerListeners) {
        listener(elapsedTime);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        MinutesAndSeconds(fontSize: widget.fontSize),
        Hundreds(fontSize: widget.fontSize),
      ],
    );
  }
}

timer_text.dart

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:timestudyapp/models/elapsed_time.dart';
import 'package:timestudyapp/viewmodels/study_viewmodel.dart';
import 'package:timestudyapp/widgets/hundreds.dart';
import 'package:timestudyapp/widgets/minutes_seconds.dart';

class TimerText extends StatefulWidget {
  final double fontSize;

  TimerText({required this.fontSize});

  TimerTextState createState() => new TimerTextState();
}

class TimerTextState extends State<TimerText> {
  late Timer timer;
  late int milliseconds;

  @override
  void initState() {
    timer = new Timer.periodic(Duration(milliseconds: 30), callback);
    super.initState();
  }

  @override
  void dispose() {
    timer.cancel();
    super.dispose();
  }

  void callback(Timer timer) {
    if (milliseconds != StudyViewModel.stopwatch.elapsedMilliseconds) {
      milliseconds = StudyViewModel.stopwatch.elapsedMilliseconds;
      final int hundreds = (milliseconds / 10).truncate();
      final int seconds = (hundreds / 100).truncate();
      final int minutes = (seconds / 60).truncate();
      final ElapsedTime elapsedTime = new ElapsedTime(
        hundreds: hundreds,
        seconds: seconds,
        minutes: minutes,
      );
      for (final listener in StudyViewModel.timerListeners) {
        listener(elapsedTime);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        MinutesAndSeconds(fontSize: widget.fontSize),
        Hundreds(fontSize: widget.fontSize),
      ],
    );
  }
}
1 Answers

Maybe the problem is in the function onTap, you should change if (isActive) to if (!isActive)

                  GestureDetector(
                    onTap: () {
                      // set active task or toggle is active
                      if (!isActive) {
                        setState(() {
                          activeTask = null;
                          StudyViewModel.stopwatch.start();
                          disable = true;
                        });
                      } else {
                        setState(() {
                          activeTask = element;
                          StudyViewModel.stopwatch.stop();
                          disable = false;
                        });
                      }
                    },
Related