मैं स्पंदन में एक टाइमर लागू कर रहा हूँ। यहाँ ऐप की संरचना है।

पेज ए (कुछ सूचियां हैं जहां उपयोगकर्ता क्लिक करता है और इसे टाइमर पेज पर ले जाता है)। पेज बी प्रारूप, टाइमर चलाता है। मैं टाइमर/स्टॉपवॉच को ठीक से चलाने में सक्षम हूं, लेकिन जब मैं पेज बी पर बैक बटन दबाता हूं तो मुझे त्रुटि को निपटाने के बाद सेटस्टेट() कहा जाता है। मैं समझता हूं कि यह अपेक्षित व्यवहार है। अगर मैं निपटान पर टाइमर.कैंसल() का उपयोग करता हूं तो मुझे त्रुटि नहीं मिल रही है, लेकिन टाइमर चलना बंद हो जाएगा। टाइमर/स्टॉपवॉच चलाना जारी रखना चाहिए, भले ही मैं पेज ए पर नेविगेट करूं या कोई अन्य नया पेज (विजेट) कहूं। मुझे पता है कि श्रोताओं और WidgetBindingObserver का उपयोग करके यह संभव हो सकता है, लेकिन मुझे इसे लागू करने का कोई स्पष्ट ज्ञान नहीं है। आशा है कि मुझे इस मुद्दे पर कुछ मदद मिलेगी।

पेज बी का निर्माण वर्ग:

  Widget build(BuildContext context) {
return Scaffold(
    appBar: AppBar(
      leading: new IconButton(icon: new Icon(Icons.arrow_back), onPressed: ()async{
        Navigator.pop(context,widget._elapsedTime);
      }),
      title: Text("widget.title"),
    ),
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text(
            '$_elapsedTime'),
          RaisedButton(
            child: Text('Start'),
            onPressed: () { 
              if(watch.isRunning){
                stopWatch();
              }
              else{
               startWatch();
              }
            },
          ),

        ],
      ),
    ));

स्टार्टवॉच फ़ंक्शन:

startWatch() {
watch.start();
timer = new Timer.periodic(new Duration(milliseconds:1000), updateTime);}

अपडेट टाइम फंक्शन जिसे हर सेकेंड कहा जाता है:

updateTime(Timer timer) {
   if (watch.isRunning) {
   print(_elapsedTime);
   var time= formatedTime(watch.elapsedMilliseconds);
   print("time is"+time);
   setState(() {
        _elapsedTime = time;
   });
 }
9
ganraj kelkar 9 नवम्बर 2018, 18:48

1 उत्तर

सबसे बढ़िया उत्तर

यहां एक न्यूनतम कामकाजी समाधान है। प्रमुख बिंदु:

  • एक TimerService वर्ग का परिचय जो टाइमर की कार्यक्षमता को अलग करता है
  • TimerService ChangeNotifier लागू करता है, जिसे आप परिवर्तन प्राप्त करने के लिए सदस्यता ले सकते हैं।
  • आपके ऐप के सभी विजेट्स को सेवा प्रदान करने के लिए एक InheritedWidget का उपयोग किया जाता है। यह विरासत में मिला विजेट आपके ऐप विजेट को लपेटता है।
  • AnimatedBuilder का उपयोग ChangeNotifier से परिवर्तन प्राप्त करने के लिए किया जाता है। सदस्यताएं स्वचालित रूप से संभाली जाती हैं (कोई मैनुअल addListener/removeListener नहीं)।

import 'dart:async';

import 'package:flutter/material.dart';

void main() {
  final timerService = TimerService();
  runApp(
    TimerServiceProvider( // provide timer service to all widgets of your app
      service: timerService,
      child: MyApp(),
    ),
  );
}

class TimerService extends ChangeNotifier {
  Stopwatch _watch;
  Timer _timer;

  Duration get currentDuration => _currentDuration;
  Duration _currentDuration = Duration.zero;

  bool get isRunning => _timer != null;

  TimerService() {
    _watch = Stopwatch();
  }

  void _onTick(Timer timer) {
    _currentDuration = _watch.elapsed;

    // notify all listening widgets
    notifyListeners();
  }

  void start() {
    if (_timer != null) return;

    _timer = Timer.periodic(Duration(seconds: 1), _onTick);
    _watch.start();

    notifyListeners();
  }

  void stop() {
    _timer?.cancel();
    _timer = null;
    _watch.stop();
    _currentDuration = _watch.elapsed;

    notifyListeners();
  }

  void reset() {
    stop();
    _watch.reset();
    _currentDuration = Duration.zero;

    notifyListeners();
  }

  static TimerService of(BuildContext context) {
    var provider = context.inheritFromWidgetOfExactType(TimerServiceProvider) as TimerServiceProvider;
    return provider.service;
  }
}

class TimerServiceProvider extends InheritedWidget {
  const TimerServiceProvider({Key key, this.service, Widget child}) : super(key: key, child: child);

  final TimerService service;

  @override
  bool updateShouldNotify(TimerServiceProvider old) => service != old.service;
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Service Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    var timerService = TimerService.of(context);
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: AnimatedBuilder(
          animation: timerService, // listen to ChangeNotifier
          builder: (context, child) {
            // this part is rebuilt whenever notifyListeners() is called
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text('Elapsed: ${timerService.currentDuration}'),
                RaisedButton(
                  onPressed: !timerService.isRunning ? timerService.start : timerService.stop,
                  child: Text(!timerService.isRunning ? 'Start' : 'Stop'),
                ),
                RaisedButton(
                  onPressed: timerService.reset,
                  child: Text('Reset'),
                )
              ],
            );
          },
        ),
      ),
    );
  }
}
25
boformer 9 नवम्बर 2018, 18:06