Reputation: 21
I am learning Flutter/Dart, specifically, how to draw on the Canvas.
I want to draw multiple lines using a FOR loop. I want a delay between iterations, so that I see each line painted individually, one after another.
Referencing these two articles:
Asynchronous Programming: Futures https://www.dartlang.org/tutorials/language/futures
Asynchronous Programming: Streams https://www.dartlang.org/tutorials/language/streams
I was able to write a 'text version' line painter to show I could delay a running FOR loop and print some text.
// print 10 lines 'text version'
Future printTenLines() async {
for (int z = 0; z <= 9; z++) {
await addDelay();
print('Line $z');
}
}
main() {
printTenLines();
}
const delayTime = Duration(milliseconds: 1000);
Future addDelay() => Future.delayed(delayTime);
But when I substitute the actual canvas.drawLine() function for the 'text version' print() routine, I get exception errors.
const delayTime = Duration(milliseconds: 10);
Future<String> addDelay() => Future.delayed(delayTime);
// draw 10 lines on the canvas
Future<void> drawTenLines() async {
for (double i = 0; i <= 100; i += 10) {
await addDelay();
print('Line $i');
canvas.drawLine(
Offset(size.width/2, size.height/2),
Offset(i, 0),
paint,
);
}
drawTenLines();
I found this problem to be similar to trying to print the output of two nested loops. Code executes, and the output of both loops is printed when the outer loop is completed.
I tried nested loops for painting the lines, with the outer loop painting the lines, and the inner loop acting as the delay timer. The program waits until both loops complete, and all the lines are drawn at once.
Using this example of asynchronous Futures and Streams is the closest I got to achieving the desired result. The 'text version" line printer is delayed and works correctly. But the delay will not work with canvas.drawLine().
Here is my complete code. It works as is and draws 10 lines. Un-comment the delay call to see the exception. I just want canvas to delay for some given time before drawing the next line.
`
import 'package:flutter/material.dart';
import 'dart:async';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Drawing Lines",
home: DrawingPage(),
);
}
}
class DrawingPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Draw Ten Lines"),
),
body: CustomPaint(
painter: LinePainter(),
child: Center(
child: Text(
"",
style: TextStyle(fontSize: 20, fontStyle: FontStyle.italic),
),
),
));
}
}
class LinePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
var paint = Paint();
paint.color = Colors.blue;
paint.strokeWidth = 1;
paint.style = PaintingStyle.stroke;
const delayTime = Duration(milliseconds: 1000);
Future<void> addDelay() => Future.delayed(delayTime);
Future<void> drawTenLines() async {
for (double i = 0; i <= 100; i += 10) {
//await addDelay();
print('Line $i');
canvas.drawLine(
Offset(size.width / 2, size.height / 2),
Offset(i, 0),
paint,
);
//await addDelay();
}
}
drawTenLines();
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
`
Upvotes: 2
Views: 537
Reputation: 489
Try this way..
Future.delayed(const Duration(milliseconds: 500), () {
// Here you can write your code
setState(() {
// Here you can write your code for open new view
});
});
second way.. Used Timer
Timer _timer;
_timer = new Timer(const Duration(milliseconds: 400), () {
setState(() {
// Here you can write your code for open new view
});
});
Timer import 'dart:async'
Upvotes: 1