flutterdartwaveformflutter-custompainter

Custom painter painting outside of the screen for new incoming data?


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?


Solution

  • 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