【问题标题】:Flutter + Riverpod: Calling a function in a stateful widget?Flutter + Riverpod:在有状态小部件中调用函数?
【发布时间】:2021-07-03 10:37:52
【问题描述】:

我正在构建一个应该通过按下按钮触发的计时器。计时器是通过有状态小部件中的代码完成的,整个设置非常简单。但是,我的问题是,在小部件树中,启动计时器的按钮与计时器本身相距甚远,我不知道如何触发从该按钮启动计时器的方法。

我知道我可以将函数作为参数传递,但这对于这个项目来说并不实用。理想情况下,我想使用 Riverpod 连接小部件,可以这样做吗? (对不起,如果这是一个愚蠢的问题,我对 Flutter 和 Riverpod 很陌生)。

我的计时器代码:

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

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

class _SimpleTimerState extends State<SimpleTimer>
    with TickerProviderStateMixin {
  late Ticker _ticker;
  Duration elapsedTime = Duration.zero;

  @override
  void initState() {
    super.initState();
    _ticker = this.createTicker(
      (elapsed) => setState(() => elapsedTime = elapsed),
    );
  }

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

  void startTimer() => _ticker.start();

  @override
  Widget build(BuildContext context) {
    return Text(elapsedTime.inSeconds.toString());
  }
}

以及按钮的代码

class TimerStartButton extends StatelessWidget {
  const TimerStartButton({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {}, // how to call startTimer from SimpleTimer here? 
      child: Text('start timer'),
    );
  }
}

【问题讨论】:

标签: flutter riverpod


【解决方案1】:

啊,在 xion 在 cmets 中发布的教程的帮助下弄明白了。如果有人正在寻找解决方案,我接近它的方法是使用返回 true 或 false 的 StateProvider(如果代码处于活动状态),然后在计时器小部件内部,我使用 ProviderListener 运行一个函数,如果那个计时器改变了。

计时器的新代码:

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

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

class _SimpleTimerState extends State<SimpleTimer>
    with TickerProviderStateMixin {
  late Ticker _ticker;
  Duration elapsedTime = Duration.zero;

  @override
  void initState() {
    super.initState();
    _ticker = this.createTicker((elapsed) {
      setState(() {
        elapsedTime = elapsed;
      });
    });
  }

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

  void startTicker() => _ticker.start();

  @override
  Widget build(BuildContext context) {
    return Consumer(
      builder: (
        BuildContext context,
        ScopedReader watch,
        Widget? child,
      ) {
        return ProviderListener(
          onChange: (context, state) => startTicker(),
          provider: timerProvider,
          child: Text(
            elapsedTime.inSeconds.toString(),
          ),
        );
      },
    );
  }
}

启动按钮的新代码:

class TimerStartButton extends ConsumerWidget {
  const TimerStartButton({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, ScopedReader watch) {
    return ElevatedButton(
      onPressed: () => context.read(timerProvider).state = true,
      child: Text('start'),
    );
  }
}

现在还添加了一个 Riverpod StateProvder:

final timerProvider = StateProvider<bool>((ref) {
  return false;
});

【讨论】:

    猜你喜欢
    • 2018-11-06
    • 1970-01-01
    • 2019-09-23
    • 2019-06-10
    • 1970-01-01
    • 2018-12-04
    • 2022-09-27
    • 2018-09-01
    • 1970-01-01
    相关资源
    最近更新 更多