简体   繁体   中英

flutter Riverpod moving the parameters from a State Notifier class into a function inside the class

I'm new to flutter and very new to riverpod. I've just been helped with some code to use a countdown clock that can then be viewed on multiple pages using Riverpod. here is the Riverpod State Notifier.

final countDownControllerProvider = StateNotifierProvider.family
    .autoDispose<CountdownController, Duration, Duration>(
        (ref, initialDuration) {
  return CountdownController(initialDuration);
});

class CountdownController extends StateNotifier<Duration> {
  Timer? timer;
  final Duration initialDuration;

  CountdownController(this.initialDuration) : super(initialDuration) {
    stopTimer();
  }

  void startTimer() {
    timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      if (state == Duration.zero) {
        timer.cancel();
      } else {
        if (mounted) {
          state = state - const Duration(seconds: 1);
        } else {
          timer.cancel();
        }
      }
    });
  }
}

Currently, the input for the time to display on the countdown clock is inputted when you call CountdownController. (the class with startTimer function inside it). the problem I'm having is if I want to call startTimer(), I need to reinput the time to display which is a problem if I'm stopping and starting the clock.

how would I move the time input from a parameter of the CountdownController class, into a function inside the class that I can then call on when needed so I don't have to set it when starting/stopping the clock? and what would that code look like?

thanks so much

I didn't test it. If you need to save duration to state, consider making the state a data class.

EDIT: tested.

import 'dart:math';

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

void main() {
  runApp(const ProviderScope(child: App()));
}

final countDownControllerProvider =
    StateNotifierProvider.autoDispose<CountdownController, Timer?>((ref) {
  return CountdownController(ref);
});

final counterProvider = StateProvider((_) => 0);
final intervalProvider = StateProvider((_) => Duration(seconds: 1));

class CountdownController extends StateNotifier<Timer?> {
  CountdownController(this.ref) : super(null);

  final Ref ref;

  void startTimer() {
    state?.cancel();
    state = Timer.periodic(ref.read(intervalProvider), (timer) {
      ref.read(counterProvider.notifier).state++;
    });
  }

  void stopTimer() {
    state?.cancel();
  }

  void accelerate(double multiplier) {
    final duration = ref.read(intervalProvider);
    ref.read(intervalProvider.notifier).state = Duration(
      milliseconds: (duration.inMilliseconds * (1 / multiplier)).floor(),
    );
    startTimer();
  }

  void speedUp() {
    accelerate(sqrt2);
  }

  void speedDown() {
    accelerate(1 / sqrt2);
  }
}

class App extends ConsumerWidget {
  const App();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final counter = ref.watch(counterProvider);
    final controller = ref.watch(countDownControllerProvider.notifier);
    final timer = ref.watch(countDownControllerProvider);

    return MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
            Text("$counter", style: Theme.of(context).textTheme.headlineLarge),
            SizedBox(height: 24),
            Row(children: [
              SizedBox(width: 24),
              Expanded(
                child: ElevatedButton(
                  onPressed: controller.startTimer,
                  child: Text(timer == null ? "start" : "stop"),
                ),
              ),
              SizedBox(width: 24),
              Expanded(
                child: ElevatedButton(
                  onPressed: controller.speedUp,
                  child: Text("+"),
                ),
              ),
              SizedBox(width: 24),
              Expanded(
                child: ElevatedButton(
                  onPressed: controller.speedDown,
                  child: Text("-"),
                ),
              ),
              SizedBox(width: 24),
            ]),
          ]),
        ),
      ),
    );
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM