Home > Software design >  How to update data and restart the timer on click?
How to update data and restart the timer on click?

Time:05-07

I have data in the application and the exchange rate is updated by a timer every 5 seconds. How can I make it so that when a floatingButton is clicked, the data is updated and the timer is restarted and replays 5 seconds. How can this be implemented? My code:

  late final Timer timer;

  @override
  void initState() {
    fetchCurrency();
    timer = Timer.periodic(
      const Duration(seconds: 5),
      (Timer t) => fetchCurrency(),
    );
    super.initState();
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Currencies'),
        centerTitle: true,
      ),
      body: ListView.builder(
        itemCount: currencyList.length,
        itemBuilder: (context, index) {
          return CurrencyCard(
            name: currencyList[index].name,
            baseName: currencyList[index].baseName,
            buy: currencyList[index].buy,
            sale: currencyList[index].sale,
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        child: const Icon(Icons.update_sharp),
      ),
    );
  }

CodePudding user response:

So I would suggest another solution without using timer but Stream

StreamSubscription? _timerSubs;

void startTimer() async {
  await endTimer();
  _timerSubs = Stream.periodic(const Duration(seconds: 5)).listen((event) {
    fetchCurrency();
  });
}

Future<void> endTimer() async {
  await _timerSubs?.cancel();
}

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

@override
void dispose() {
  endTimer();
  super.dispose();
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: const Text('Currencies'),
      centerTitle: true,
    ),
    body: ListView.builder(
      itemCount: currencyList.length,
      itemBuilder: (context, index) {
        return CurrencyCard(
          name: currencyList[index].name,
          baseName: currencyList[index].baseName,
          buy: currencyList[index].buy,
          sale: currencyList[index].sale,
        );
      },
    ),
    floatingActionButton: FloatingActionButton(
      onPressed: startTimer,
      child: const Icon(Icons.update_sharp),
    ),
  );
}

CodePudding user response:

I would remove the final modifier in timer variable

late Timer timer;

and in onTap in FloatingActionButton I call cancel method and recreate new timer:

  floatingActionButton: FloatingActionButton(
    onPressed: () {
       timer.cancel();
       timer = Timer.periodic(
       const Duration(seconds: 5),
       (Timer t) => fetchCurrency(),
       );
    },
    child: const Icon(Icons.update_sharp),
  ),
  • Related