So i'm trying to make a Voronoi Diagram application using image library. So this algoritm is quite slow, so when the button is pressed I want my not to stutter and show CircularProgressindicator, and then when computions are finished and Image is ready I want to see the image from Uint8List
class _VoronoiPageState extends State<VoronoiPage> {
final TextEditingController textEditingControllerWidth = TextEditingController();
final TextEditingController textEditingControllerHeight = TextEditingController();
final TextEditingController textEditingControllerStations = TextEditingController();
Future<Uint8List> ?diagramImage;
Uint8List createDiagram() {
int width = 0;
int height = 0;
int basedStation = 0;
setState(() {
width = int.tryParse(textEditingControllerWidth.text) ?? 0;
height = int.tryParse(textEditingControllerHeight.text) ?? 0;
basedStation = int.tryParse(textEditingControllerStations.text) ?? 0;
});
// Creating new image
img.Image diagram = img.Image(width: width, height: height);
print('image created');
List<DrawPixels> baseStationList = generatePixels(basedStation, width, height);
for (var pixel in baseStationList) {
pixel.color = generateRandomColor();
}
// Drawingf the diagram
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
double minDistance = double.infinity;
int minIndex = -1;
for (int k = 0; k < basedStation; k++) {
double distance = calculateDistance(i, j, baseStationList[k].x, baseStationList[k].y);
if (distance < minDistance) {
minDistance = distance;
minIndex = k;
}
}
img.drawPixel(diagram, i, j, baseStationList[minIndex].color);
}
}
for (var pixel in baseStationList) {
img.fillCircle(diagram, x: pixel.x, y: pixel.y, radius: 3, color: img.ColorFloat16.rgb(255, 255, 255));
}
return img.encodePng(diagram);
}
Future<Uint8List> drawDiagram() async {
try {
final data = await Future.value(createDiagram());
return data;
} catch (e) {
throw Exception('pizdec');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Voronoi Diagram'),
),
body: Center(
child: Column(
children: [
FutureBuilder(
future: diagramImage,
builder: (context, AsyncSnapshot<Uint8List> snapshot) {
if (snapshot.hasData == false) {
return const Icon(Icons.image, );
}
if (snapshot.connectionState == ConnectionState.waiting) {
print('connection state waiting');
return const CircularProgressIndicator();
}
print('begin');
return Image.memory(snapshot.data!);
},
),
MyTextField(
hintText: 'Enter width',
textEditingController: textEditingControllerWidth,
),
MyTextField(
hintText: 'Enter heigth',
textEditingController: textEditingControllerHeight,
),
MyTextField(
hintText: 'Enter amount of stations',
textEditingController: textEditingControllerStations,
),
ElevatedButton(
onPressed: () {
diagramImage = drawDiagram();
},
child: const Text('Create diagram'),
)
],
),
),
);
}
}
I tried using FutureBuilder, but somehow connectionState = ConnectionState.waiting is showing only when everything is ready, so my app is just stuttering until all computions are done.
You are calling the setState inside the function, but you need to rebuild the app when click the button.
Edit 2: Based on your project at GB, change your drawDiagrama function to
Edit 2:
Change the if inside your FutureBuilder to