Create Timer With Given Data

Issue

I have an app which gets hours and minutes from the backend. Every time the app is called the data from the backend gets saved in shared preferences. When he user has no internet connection I show the same screen as the user saw when having internet just using the data saved in shared preferences instead. One of the parts of the data is a timer which I get the hours and minutes from the backend, and the hours and minutes get updated every time I make the API call. What I want now is to have the data from shared preferences to create a timer with the data saved in shared preferences. I need to have the minutes and hours update and work just like it would with the normal data with internet connection. So when there is no internet connection we display the data and I need to create the timer to update the minutes and the hours so the user can see the timer update even when there is no internet. So if the minutes and hours in shared preferences are saved like: 1hr : 6mins. I need to make it so the time keeps going and minutes and hours keep updating. So after 60 secs mins will be 7mins, and after 54mins hours will be 2hrs, And the process starts right when the screen is opened without any start button.

// Saving data from api in shared preferences

 body: FutureBuilder<Response>(
        future: futureDataForStatus,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done &&
              snapshot.hasData) {
            accountInfo = WorkingLocationStatus.fromJson(
              json.decode(snapshot.data!.body),
            );

            final duration = IsoDuration.parse(
              accountInfo!.duration.toString(),
            );

            prefs.setDouble('workingHours', duration.hours);
            prefs.setDouble('workingMinutes', duration.minutes);

            return Column(

   // Displaying the saved data 

class OffilneWorkingHoursMinutes extends StatefulWidget {
  const OffilneWorkingHoursMinutes({Key? key}) : super(key: key);

  @override
  State<OffilneWorkingHoursMinutes> createState() =>
      _OffilneWorkingHoursMinutesState();
}

class _OffilneWorkingHoursMinutesState
    extends State<OffilneWorkingHoursMinutes> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(
        '${prefs.getDouble('workingHours')!.toStringAsFixed(0)} hrs - '
        '${prefs.getDouble('workingMinutes')!.toStringAsFixed(0)} mins ',
        style: const TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
      ),
    );
  }
}

Solution

Look at this example, I think it could help, just adjust it to your needs:

class OffilneWorkingHoursMinutes extends StatefulWidget {
  const OffilneWorkingHoursMinutes({Key? key}) : super(key: key);

  @override
  State<OffilneWorkingHoursMinutes> createState() =>
      _OffilneWorkingHoursMinutesState();
}

class _OffilneWorkingHoursMinutesState
    extends State<OffilneWorkingHoursMinutes> {
  var time = Time(hours: 1, minutes: 6, seconds: 0); // pass your time from backend here
  @override
  void initState() {
    Timer.periodic(const Duration(seconds: 1), (timer) { // use timer when you are offline and cancel it when you are back online
      setState(() {
        if (time.seconds < 59) {
          time.seconds++;
        } else {
          if (time.minutes < 59) {
            time.minutes++;
          } else {
            time.minutes = 0;
            time.hours++;
          }
          time.seconds = 0;
        }
      });
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(
        '${time.hours} hrs - '
        '${time.minutes} mins - '
        '${time.seconds} sec ',
        style: const TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
      ),
    );
  }
}

class Time {
  int hours;
  int minutes;
  int seconds;
  Time({
    this.hours = 0,
    this.minutes = 0,
    this.seconds = 0,
  });
}

Answered By – Ante Bule

Answer Checked By – Robin (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.