flutter 如何解决在使用Riverpod进行状态管理时“The method 'read' is not defined for the type 'BuildContext'”错误?

btqmn9zl  于 2023-06-24  发布在  Flutter
关注(0)|答案(1)|浏览(229)

我试图在Flutter应用程序中使用Riverpod作为状态管理解决方案。我有一个CountDownController类,它创建了一个动画控制器,还有一个PomodoroIntervals小部件,它使用CountDownController来管理一些倒计时逻辑。但是,当我试图从BuildContext访问read方法时,遇到了以下错误:
未为类型“BuildContext”定义方法“read”。尝试将名称更正为现有方法的名称,或定义名为“read”的方法。dartundefined_method
这个错误发生在PomodoroIntervals小部件的initState方法中,我试图使用Riverpod提供程序的read方法初始化_countDownController变量:

_countDownController = context.read(countDownControllerProvider);

此外,在尝试访问CountDownController类的timerString属性时,我还遇到了另一个错误:
未为类型“CountDownController”定义getter“timerString”。尝试导入定义'timerString'的库,将名称更正为现有getter的名称,或定义名为'timerString'的getter或字段。
此错误发生在PomodoroIntervals小部件的notify方法中:

if (_countDownController.timerString == '00:00:00') {
  _tabController.animateTo(1, duration: const Duration(milliseconds: 300));
}

这是完整的代码,它为这两个问题提供了上下文:

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

final countDownControllerProvider =
    Provider<CountDownController>((ref) => CountDownController());

class CountDownController {
  late AnimationController controller;

  void createAnimationController(TickerProvider tickerProvider) {
    controller = AnimationController(
      vsync: tickerProvider,
      duration: const Duration(seconds: 60),
    );
  }
}

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

  @override
  State<PomodoroIntervals> createState() => _PomodoroIntervalsState();
}

class _PomodoroIntervalsState extends State<PomodoroIntervals>
    with TickerProviderStateMixin {
  late TabController _tabController;
  late CountDownController _countDownController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this, initialIndex: 0);
    _countDownController = context.read(countDownControllerProvider.notifier);
    _countDownController.createAnimationController(this);
  }

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

  void notify() {
    if (_countDownController.timerString == '00:00:00') {
      _tabController.animateTo(1, duration: const Duration(milliseconds: 300));
    }
  }

  double progress = 1.0;
  bool LongBreak = true;

  @override
  Widget build(BuildContext context) {
    return ProviderScope(
      child: SizedBox(
        height: MediaQuery.of(context).size.height,
        width: double.infinity,
        child: AnimatedBuilder(
          animation: _countDownController.controller,
          builder: (context, child) {
            return DefaultTabController(
              length: 3,
              child: Scaffold(
                appBar: AppBar(
                  elevation: 0,
                  backgroundColor: Colors.transparent,
                  bottom: PreferredSize(
                    preferredSize: const Size.fromHeight(22),
                    child: Container(
                      color: Colors.transparent,
                      child: SafeArea(
                        child: Column(children: [
                          TabBar(
                            controller: _tabController,
                            indicator: const UnderlineTabIndicator(
                              borderSide:
                                  BorderSide(color: Color(0xff3B3B3B), width: 2.0),
                              insets: EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 12.0),
                            ),
                            indicatorWeight: 5,
                            indicatorSize: TabBarIndicatorSize.label,
                            labelColor: const Color(0xff3B3B3B),
                            labelStyle: GoogleFonts.nunito(
                              fontSize: 16.0,
                              fontWeight: FontWeight.w500,
                            ),
                            unselectedLabelColor: const Color(0xffD7D7D7),
                            tabs: const [
                              Tab(
                                text: "Pomodoro",
                                icon: Icon(Icons.work_history_outlined, size: 24),
                              ),
                              Tab(
                                text: "Short break",
                                icon: Icon(Icons.ramen_dining_outlined, size: 24),
                              ),
                              Tab(
                                text: "Long break",
                                icon: Icon(Icons.battery_charging_full_outlined, size: 24),
                              ),
                            ],
                          ),
                        ]),
                      ),
                    ),
                  ),
                ),
                body: TabBarView(
                  controller: _tabController,
                  children: const <Widget>[
                    Center(
                      child: Text('Short break'),
                    ),
                    Center(
                      child: Text('Short break'),
                    ),
                    Center(child: Text('Long break')),
                  ],
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

我已经检查了进口,并确保必要的包包括在内。如何解决这些错误并在Flutter应用程序中成功使用Riverpod进行状态管理?

axr492tv

axr492tv1#

这是正确的,因为context没有这样的参数。下面是如何做到这一点(并使用ConsumerStatefulWidget):

class PomodoroIntervals extends ConsumerStatefulWidget {
  const PomodoroIntervals ({super.key});

  @override
  ConsumerState createState() => _PomodoroIntervalsState();
}

class _PomodoroIntervalsState extends ConsumerState<PomodoroIntervals> {
  @override
  void initState() {
    ...
    _countDownController = ref.read(countDownControllerProvider);
  }

  @override
  Widget build(BuildContext context) {
    ref.watch(myProvider); // and here...
    return Container();
  }
}

ref示例作为ConsumerStatefulWidget类的字段提供

相关问题