I was trying to make a web app to visualise algorithm in flutter, I came across a short youtube video ( https://www.youtube.com/watch?v=IMK4yqlT24Q&t=672s) explaining it and I did a small test and it did work. Now when I want to build a complete web app it doesnt work. The way it is supposed to work is the list gets updated every cycle of loop while sorting and it gets printed. I tried using both Stream BUilder and set state for updating the UI but what happens is, A few bars moves for a second and then it stops
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List<int> numbers = [];
int sample = 500;
@override
void initState() {
super.initState();
random();
}
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
int counter = 0;
return SafeArea(
child: Row(
children: [
Container(
height: size.height,
width: size.width * 0.2,
color: Colors.purple.shade500,
child: Column(
children: [
SizedBox(
height: 30,
width: double.infinity,
child: MaterialButton(
onPressed: random,
child: Text('Randomise'),
),
),
SizedBox(
height: 30,
width: double.infinity,
child: MaterialButton(
onPressed: sort,
child: Text('Sort'),
),
),
],
),
),
Container(
width: size.width * 0.8,
height: size.height,
color: Colors.white38,
child: Align(
alignment: Alignment.center,
child: SizedBox(
height: 600,
width: 1000,
child: Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: numbers.map((int number){
counter ;
return CustomPaint( <-----Painting every bar of array
painter: BarPainter(number: number, index: counter, width: 2.0),
);
}).toList(),
),
),
),
),
),
],
),
);
}
random() {
numbers = [];
for (var i = 0; i < sample; i ) {
numbers.add(Random().nextInt(sample));
}
setState(() {});
}
sort() async{
for (var i = 0; i < numbers.length - 1; i ) {
for (var k = 0; k < numbers.length - 1 - i; k ) {
if (numbers[k] > numbers[k 1]) {
var temp = numbers[k];
numbers[k] = numbers[k 1];
numbers[k 1] = temp;
}
await Future.delayed(Duration(microseconds: 50));
setState(() { <----updating build every loop
});
}
}
}
}
I know calling setState everytime is not good, but I did it just for testing, I usually put the row inside a Stream builder and keep adding the number list as a stream, which used to work fine. If I print a dummy counter inside the nested for of sort function, I can see that the loop is running, but for sume reason the Custom Paint doest seem to be updating the UI even if the delay time for the loop is increased.
class BarPainter extends CustomPainter {
final double width;
final int index;
final int number;
BarPainter({required this.number, required this.index, required this.width});
@override
void paint(Canvas canvas, Size size) {
Paint paint = Paint();
paint.strokeWidth = width;
paint.strokeCap = StrokeCap.square;
paint.color = Colors.black;
canvas.clipRect(Rect.fromLTRB(0, 0, 1000, 600));
canvas.drawLine(Offset(index * width, 0),
Offset(index * width, number.ceilToDouble()), paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return false;
}
}
CodePudding user response:
You can return true from shouldRepaint. I do shortcut like oldDelegate != this;.
Check this question When is shouldRepaint method from custom painter class in flutter called?
@override
bool shouldRepaint(covariant BarPainter oldDelegate) {
return oldDelegate != this;
}
