Я пытаюсь клонировать таймер приложения, которое я использую во время тренировки: Сильный.До сих пор мне удалось реализовать все основные функции и анимации (которых немного).Я знаю, что мой код грязный, и, возможно, есть лучшие способы реализовать то, что я пытаюсь сделать, если есть какие-то предложения, которые они также ценят.У меня две проблемы с моим заявлением.1. Когда таймер запускается, я получаю следующую ошибку:
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
╞═══════════════════════════════════════════════════════════
flutter: The following NoSuchMethodError was thrown building Peinture(dirty, state: _PeintureState#82e34):
flutter: The getter 'inMilliseconds' was called on null.
flutter: Receiver: null
flutter: Tried calling: inMilliseconds
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:50:5)
flutter: #1 _PeintureState.build (package:workout_timer/main.dart:241:72)
flutter: #2 StatefulElement.build (package:flutter/src/widgets/framework.dart:3809:27)
flutter: #3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3721:15)
flutter: #4 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #5 StatefulElement.update (package:flutter/src/widgets/framework.dart:3878:5)
flutter: #6 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #7 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4867:14)
flutter: #8 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #9 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #10 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #11 ProxyElement.update (package:flutter/src/widgets/framework.dart:3990:5)
flutter: #12 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #13 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #14 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #15 StatelessElement.update (package:flutter/src/widgets/framework.dart:3781:5)
flutter: #16 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #17 RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:4585:32)
flutter: #18 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4975:17)
flutter: #19 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #20 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #21 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #22 ProxyElement.update (package:flutter/src/widgets/framework.dart:3990:5)
flutter: #23 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #24 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #25 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #26 ProxyElement.update (package:flutter/src/widgets/framework.dart:3990:5)
flutter: #27 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #28 RenderObjectElement.updateChildren (package:flutter/src/widgets/framework.dart:4585:32)
flutter: #29 MultiChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4975:17)
flutter: #30 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #31 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #32 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #33 StatefulElement.update (package:flutter/src/widgets/framework.dart:3878:5)
flutter: #34 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #35 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #36 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #37 ProxyElement.update (package:flutter/src/widgets/framework.dart:3990:5)
flutter: #38 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #39 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #40 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #41 StatefulElement.update (package:flutter/src/widgets/framework.dart:3878:5)
flutter: #42 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #43 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4867:14)
flutter: #44 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #45 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #46 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #47 StatelessElement.update (package:flutter/src/widgets/framework.dart:3781:5)
flutter: #48 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #49 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4867:14)
flutter: #50 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #51 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #52 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #53 StatefulElement.update (package:flutter/src/widgets/framework.dart:3878:5)
flutter: #54 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #55 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #56 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #57 StatefulElement.update (package:flutter/src/widgets/framework.dart:3878:5)
flutter: #58 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #59 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #60 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #61 ProxyElement.update (package:flutter/src/widgets/framework.dart:3990:5)
flutter: #62 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #63 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #64 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #65 ProxyElement.update (package:flutter/src/widgets/framework.dart:3990:5)
flutter: #66 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #67 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #68 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #69 StatefulElement.update (package:flutter/src/widgets/framework.dart:3878:5)
flutter: #70 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
flutter: #71 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
flutter: #72 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
flutter: #73 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2286:33)
flutter: #74 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:676:20)
flutter: #75 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5)
flutter: #76 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
flutter: #77 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
flutter: #78 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
flutter: #79 _invoke (dart:ui/hooks.dart:154:13)
flutter: #80 _drawFrame (dart:ui/hooks.dart:143:3)
flutter: ════════════════════════════════════════════════════════════════════════════════════════════════════
, которую я обязательно проверил, я не получаю ничего нулевого, но все равно получаю это.
Ивторой.Когда таймер заканчивается, я получаю следующую ошибку:
[VERBOSE-2:shell.cc(184)] Dart Error: Unhandled exception:
setState() called after dispose(): _TimeState#10749(lifecycle state: defunct, not mounted)
This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback. The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
#0 State.setState.<anonymous closure> (package:flutter/src/widgets/framewo<…>
И когда я пытаюсь запустить таймер снова, я получаю это:
flutter: Another exception was thrown: NoSuchMethodError: The getter 'inMilliseconds' was called on null.
Вот мой код:
import 'dart:async';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:fluttery/layout.dart';
Duration time;
Duration previousTime;
Duration currentTime;
AnimationController timeController, circleController;
bool reverse = false;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
Stopwatch stopwatch = new Stopwatch();
@override
void initState() {
super.initState();
timeController = new AnimationController(
duration: const Duration(milliseconds: 250),
vsync: this,
);
timeController.addListener(() {
setState(() {});
});
}
@override
void dispose() {
timeController.dispose();
circleController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Center(
child: Opacity(
opacity: timeController.value != null ? 1.0 - timeController.value : 1.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new FlatButton(
onPressed: () {
setState(() {
previousTime = Duration(minutes: 1);
time = previousTime;
timeController.forward();
stopwatch.start();
circleController = new AnimationController(
duration: Duration(milliseconds: time.inMilliseconds),
vsync: this,
);
circleController.addListener(() {
setState(() {});
});
circleController.forward();
});
},
child: Text("1:00",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16.0)),
),
new FlatButton(
onPressed: () {
setState(() {
previousTime = Duration(minutes: 2);
time = previousTime;
timeController.forward();
stopwatch.start();
circleController = new AnimationController(
duration: Duration(milliseconds: time.inMilliseconds),
vsync: this,
);
circleController.addListener(() {
setState(() {});
});
circleController.forward();
});
},
child: Text("2:00",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16.0)),
),
new FlatButton(
onPressed: () {
setState(() {
previousTime = Duration(minutes: 3);
time = previousTime;
timeController.forward();
stopwatch.start();
circleController = new AnimationController(
duration: Duration(milliseconds: time.inMilliseconds),
vsync: this,
);
circleController.addListener(() {
setState(() {});
});
circleController.forward();
});
},
child: Text("3:00",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16.0)),
),
new FlatButton(
onPressed: () {
setState(() {
previousTime = Duration(minutes: 5);
time = previousTime;
timeController.forward();
stopwatch.start();
circleController = new AnimationController(
duration: Duration(milliseconds: time.inMilliseconds),
vsync: this,
);
circleController.addListener(() {
setState(() {});
});
circleController.forward();
});
},
child: Text("5:00",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 16.0)),
),
],
),
),
),
Center(
child: Opacity(
opacity: timeController.value != null ? 0.0 + timeController.value : 0.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: time != null ? buildTimes(stopwatch, time, previousTime) : []
),
),
),
CenterAbout(
position: Offset(MediaQuery.of(context).size.width / 2,
MediaQuery.of(context).size.height / 2),
child: Peinture(color: Color.fromRGBO(224, 245, 255, 1.0), animate: false)
),
CenterAbout(
position: Offset(MediaQuery.of(context).size.width / 2,
MediaQuery.of(context).size.height / 2),
child: Peinture(color: Colors.blue, animate: true)
)
],
),
);
}
}
List<Widget> buildTimes(stopwatch, time, previousTime) {
return [
Time(stopwatch: stopwatch, time: time),
Text(
previousTime != null
? previousTime.toString().substring(3, 7)
: "",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30.0,
color: Colors.black54),
),
];
}
class Peinture extends StatefulWidget {
final Color color;
final bool animate;
Peinture({this.color, this.animate});
@override
_PeintureState createState() => _PeintureState(color: color, animate: animate);
}
class _PeintureState extends State<Peinture> {
Timer timer;
Color color;
bool animate;
_PeintureState({this.color, this.animate}) {
timer = Timer.periodic(Duration(milliseconds: 1), callback);
}
void callback(Timer timer) {
setState(() {
if (currentTime != null) {
print(currentTime.inMilliseconds);
if (currentTime.inMilliseconds <= 0) {
reverse = true;
timeController.reverse();
previousTime = null;
time = previousTime;
currentTime = time;
reverse = false;
}
}
});
}
@override
Widget build(BuildContext context) {
return Opacity(
opacity: reverse == false ? 1.0 : timeController.value,
child: CustomPaint(
painter: CirclePainter(
radius: 150.0,
thickness: 8.0,
color: color,
startAngle: -pi / 2,
endAngle: time != null && animate ? -pi / 2 + (((currentTime.inMilliseconds - circleController.value)) / 60000) * (2*pi) : -pi / 2 + (2 * pi) - (0 / (2*pi)),
),
),
);
}
}
class CirclePainter extends CustomPainter {
final double radius;
final double thickness;
final Color color;
final double startAngle;
final double endAngle;
final Paint circlePaint;
CirclePainter({this.radius, this.thickness, this.color, this.startAngle, this.endAngle})
: circlePaint = new Paint()
..color = color
..strokeWidth = thickness
..style = PaintingStyle.stroke
..strokeCap = StrokeCap.round;
@override
void paint(Canvas canvas, Size size) {
canvas.drawArc(Rect.fromLTWH(-radius, -radius, radius * 2, radius * 2),
startAngle, endAngle - startAngle, false, circlePaint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
class Time extends StatefulWidget {
final Duration time;
final Stopwatch stopwatch;
Time({this.stopwatch, this.time});
@override
_TimeState createState() => _TimeState(stopwatch: stopwatch, time: time);
}
class _TimeState extends State<Time> {
Timer timer;
Duration time;
Stopwatch stopwatch;
_TimeState({this.time, this.stopwatch}) {
timer = new Timer.periodic(new Duration(milliseconds: 1), callback);
}
void callback(Timer timer) {
if (stopwatch.isRunning) {
setState(() {
currentTime = time - stopwatch.elapsed;
});
}
}
@override
Widget build(BuildContext context) {
return Text(
currentTime != null ? currentTime.toString().substring(3, 7) : "",
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 60.0, color: Colors.black87),
);
}
}
Спасибо за помощь, и мы будем благодарны за любые предложения относительно того, как вы поступите.