取消颤振定时器

问题描述 投票:0回答:1

我想在导航到另一个页面时停止计时器。 以下是我的代码


//imports
late Timer timer;

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var selectedIndex = 0;

  @override
  Widget build(BuildContext context) {
    Widget page;
    switch (selectedIndex) {
      case 0:
        page = const MonitorPage();
      case 1:
        page = const ReportPage();
      case 2:
        page = const Placeholder();
      default:
        throw UnimplementedError("not found");
    }
    return LayoutBuilder(builder: (context, constraints) {
      return Scaffold(
        body: Row(
          children: [
            SafeArea(
              child: NavigationRail(
                extended: constraints.maxWidth >= 600,
                destinations: const [
                  NavigationRailDestination(
                    icon: Icon(Icons.home),
                    label: Text('main'),
                  ),
                  NavigationRailDestination(
                    icon: Icon(Icons.list),
                    label: Text('report'),
                  ),
                  NavigationRailDestination(
                    icon: Icon(Icons.settings),
                    label: Text("setting"),
                  ),
                ],
                selectedIndex: selectedIndex,
                onDestinationSelected: (value) {
                  setState(() {
                    if (selectedIndex == 0) {
                      timer.cancel(); // here I'd like to cancel the timer
                    }
                    selectedIndex = value;
                  });
                },
              ),
            ),
            Expanded(
              child: Container(
                color: Theme.of(context).colorScheme.primaryContainer,
                child: page,
              ),
            )
          ],
        ),
      );
    });
  }
}


class _MonitorPageState extends State<MonitorPage> {
  late String _time;

  @override
  void initState() {
    _time =
        "${DateTime.now().year.toString().padLeft(4, '0')}-${DateTime.now().month.toString().padLeft(2, '0')}-${DateTime.now().day.toString().padLeft(2, '0')} ${DateTime.now().hour.toString().padLeft(2, '0')}:${DateTime.now().minute.toString().padLeft(2, '0')}:${DateTime.now().second.toString().padLeft(2, '0')}";
    timer = Timer.periodic(const Duration(seconds: 1), (timer) { // here i set the timer variable
      _updateTime(); //just updating time
    });
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    ...
}
}

我本来想取消计时器,但它给了我这个消息。


======== Exception caught by gesture ===============================================================
The following LateError was thrown while handling a gesture:
LateInitializationError: Field 'timer' has not been initialized.

When the exception was thrown, this was the stack: 
#0      timer (package:TPSEM_pocket/main.dart)
#1      _MyHomePageState.build.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:TPSEM_pocket/main.dart:184:23)
#2      State.setState (package:flutter/src/widgets/framework.dart:1203:30)
#3      _MyHomePageState.build.<anonymous closure>.<anonymous closure> (package:TPSEM_pocket/main.dart:182:19)
#4      _NavigationRailState.build.<anonymous closure> (package:flutter/src/material/navigation_rail.dart:463:62)
#5      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1183:21)
#6      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:315:24)
#7      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:652:11)
#8      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:309:5)
#9      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:242:7)
#10     PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:670:9)
#11     PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
#12     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
#13     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:633:13)
#14     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
#15     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
#16     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:495:19)
#17     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:475:22)
#18     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:430:11)
#19     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:420:7)
#20     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:383:5)
#21     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:330:7)
#22     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:299:9)
#23     _invoke1 (dart:ui/hooks.dart:328:13)
#24     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:429:7)
#25     _dispatchPointerDataPacket (dart:ui/hooks.dart:262:31)
Handler: "onTap"
Recognizer: TapGestureRecognizer#0c5e3
  debugOwner: GestureDetector
  state: possible
  won arena
  finalPosition: Offset(115.5, 71.5)
  finalLocalPosition: Offset(115.5, 19.5)
  button: 1
  sent tap down
====================================================================================================

这就是重点 =>

LateInitializationError: Field 'timer' has not been initialized.

我尝试使用状态变量并将其设置为计时器,然后在

onDestinationSelected
中取消它(就在更改
selectedIndex
变量之前),但它也不起作用。 我该如何解决它?谢谢。

flutter dart flutter-timer
1个回答
0
投票

timer
类中定义
_MyHomePageState
变量。这将可以在状态类中访问并且可以取消。
另外,取消
timer
方法中的
dispose()
,避免内存泄漏。

这是更新后的代码:

class _MyHomePageState extends State<MyHomePage> {
  late Timer timer; // Define timer variable here

  // Rest of your code...

  // This will call when the state object is initiate
  @override
  void initState() {
    super.initState();
    // Initialize the timer here
    timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      _updateTime(); //just updating time
    });
  }

  // This will call when the state object is removed
  @override
  void dispose() {
    // Cancel the timer when the state is disposed
    timer.cancel();
    super.dispose();
  }

  // Rest of your code...
}
© www.soinside.com 2019 - 2024. All rights reserved.