I am implementing waveform visualization for mic in my app.
class BarVisualizer extends CustomPainter {
final List<double> waveData;
BarVisualizer({
required this.waveData,
});
@override
void paint(Canvas canvas, Size size) {
for (var i = 0; i < waveData.length; i++) {
canvas.drawLine(Offset(i.toDouble() + i , 0),
Offset(i.toDouble() + i, -waveData[i]), wavePaint);
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
above for-loop
draws lines for each decibel value I get from mic.
As I am using a mic to get data, the list of decibel will get large and it start painting outside of the screen.
So my question is how can I move the previously painted lines back to paint new incoming decibel values inside the screen?
what I did was created a callback when a certain condition matches and call the setState from that call back to the offset which looks like this,
for (var i = 0; i < waveData.length; i++) {
if ((spacing * i) + offset.dx > size.width * sizeCounter) {
callback();
}
canvas.drawLine(
Offset(-scrollOffset.dx + offset.dx + (spacing * i), 100),
Offset(-scrollOffset.dx + offset.dx + (spacing * i),
-waveData[i] + 100),
wavePaint);
}
now in the UI,
CustomPaint(
painter: Barpainter(
callback:(){
WidgetsBinding.instance!.addPostFrameCallback(
(timeStamp) {
setState(
() {
scrollOffset += Offset(width, 0);
sizeCounter++;
},
);
},
);
}
)
)
this add extra offset when it reaches end of the screen