I have a music application, I want to display music notes each second with a svg file. I have a music keyboard provider that notifies every second, all listeners. Each time, it rebuilds the widget I think completely. I use a controller to load an svg file to render music notes on a music staff (bunch of music notes). The widget is lagging and there's a flash every second.
class StaffView extends StatelessWidget {
late Future<String> _svgFuture;
late String _currentSvg = "";
@override
Widget build(BuildContext context) {
final ScaleProvider scaleProvider = context.watch<ScaleProvider>();
Scale? myScale = scaleProvider.getScale();
PianoKeysProvider pkp = context.watch<PianoKeysProvider>();
int noteScalePosition = pkp.getIndexPosition();
//Faire la validation
if(_currentSvg == "")
{
_svgFuture = GenerateStaffSvg(myScale, noteScalePosition);
pkp.RestartScale();
}
How can I use the provider and watch for change every seconds and not rebuild the widget completely every time? Will it be useful to use a stafeful widget and use a setstate to rebuild just the svg?
The build :
return FutureBuilder<String>(
future: _svgFuture,
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error : ${snapshot.error}');
} else {
_currentSvg = snapshot.data!;
return Expanded(
child: Container(
color: Colors.white,
child: SingleChildScrollView(
child: FittedBox(
fit: BoxFit.fill,
child: SvgPicture.string(
_currentSvg,
width: 500,
height: 500,
),
),
),
),
);
}
},
);
Where the widget is called :
child: Container(
color:Colors.black,
child: Column(
children: [
// First child, an empty space
Conditional.single(
context: context,
conditionBuilder: (BuildContext context) => _heightRatio == 2,
widgetBuilder: (BuildContext context) => Flexible(
flex: 3,
child: StaffView(
),
),
fallbackBuilder: (BuildContext context) => Container(),
),
// Second child, the piano keyboard
Flexible(
flex: 1,
child: Consumer<PianoKeysProvider>(
builder: (context, pianoKeysProvider, child) {
return ListView.builder(
itemCount: 7,
scrollDirection: Axis.horizontal,
controller: ScrollController(initialScrollOffset: 1500.0),
itemBuilder: (BuildContext context, int index) {
final int i = index * 12;
Thank you so much
I tried using the snapshot data to avoid loading the svg image all the time, but I have the same problem.