Search code examples
flutterdartsetstateflutter-widget

flutter_gauge widget won't update index value on setState


The problem I'm having is that although I'm successfully updating a value of my meter (FlutterGauge) widget via setState, the widget itself does not reflect that change. I know that the rebuild is happening, and that the value on the meter widget is indeed being updated.


void updateScore(bool isOnTopic) {
    //for the purposes of testing we won't use isOnTopic (its a hardcoded true anyway)
    setState(() {
      meterScore += 15;
    });
    print("Score Updated:");
    print("--------" + meterScore.toString() + "--------");
  }

  @override
  Widget build(BuildContext context) {
    print('+++++++We\'re building! Using this.meterScore value: ' +
        meterScore.toString() +
        '+++++++');

    //Replacing my FlutterGauge and return with the line below as a way to isolate the FlutterGauge widget as the problem
    //return Center(child: Text(this.meterScore.toString()));

    FlutterGauge meter = new FlutterGauge(
        circleColor: meterColor,
        secondsMarker: SecondsMarker.none,
        hand: Hand.short,
        number: Number.none,
        width: 200,
        index: meterScore,
        fontFamily: "Iran",
        counterStyle: TextStyle(color: Colors.black, fontSize: 35),
        counterAlign: CounterAlign.center,
        isDecimal: false);
    print("------------Accessing meter.index: " +
        meter.index.toString() +
        "----------------");
    return meter;
  }

I'm fairly certain that the issue is how I'm using the FlutterGauge widget from the flutter_gauge package because when I replace it with a simple Text widget, and feed my value to it, it will update and reflect the update as expected.

That being the case, here is a link to flutter_gauge for reference: https://pub.dev/packages/flutter_gauge#-readme-tab-

I'm pretty new to flutter and this is my first stackoverflow question, so apologies if I'm making any obvious mistakes. Thanks in advance!

Just in case there's important code I'm leaving out that you may need to see, here is the entire file:

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_gauge/flutter_gauge.dart';

class Meter extends StatefulWidget {
  Meter({Key key}) : super(key: key);
  MeterState createState() => MeterState();
}

class MeterState extends State<Meter> {
  @override
  initState() {
    super.initState();
  }

  double meterScore = 75;
  Color meterColor = Colors.green;

  void updateMeterColor() {
    setState(() {
      meterColor = Colors.green;
    });
  }

  void updateScore(bool isOnTopic) {
    //for the purposes of testing we won't use isOnTopic (its a hardcoded true anyway)
    setState(() {
      meterScore += 15;
    });
    print("Score Updated:");
    print("--------" + meterScore.toString() + "--------");
  }

  @override
  Widget build(BuildContext context) {
    print('+++++++We\'re building! Using this.meterScore value: ' +
        meterScore.toString() +
        '+++++++');

    //Replacing my FlutterGauge and return with the line below as a way to isolate the FlutterGauge widget as the problem
    //return Center(child: Text(this.meterScore.toString()));

    FlutterGauge meter = new FlutterGauge(
        circleColor: meterColor,
        secondsMarker: SecondsMarker.none,
        hand: Hand.short,
        number: Number.none,
        width: 200,
        index: meterScore,
        fontFamily: "Iran",
        counterStyle: TextStyle(color: Colors.black, fontSize: 35),
        counterAlign: CounterAlign.center,
        isDecimal: false);
    print("------------Accessing meter.index: " +
        meter.index.toString() +
        "----------------");
    return meter;
  }

  @override
  void dispose() {
    print("---------We are disposing (as intended)------------");
    super.dispose();
  }
}

EDITS: here is my terminal after a hot restart and initial visit:

I/flutter (11573): +++++++We're building! Using this.meterScore value: 75.0+++++++
I/flutter (11573): ------------Accessing meter.index: 75.0----------------
I/flutter (11573): 75.0

invoking the function once:

I/flutter (11573): Score Updated:
I/flutter (11573): --------90.0--------
I/flutter (11573): +++++++We're building! Using this.meterScore value: 90.0+++++++
I/flutter (11573): ------------Accessing meter.index: 90.0----------------

I updated the code snippets (removed the this. from all meterScore, added a comment addressing the function's unused argument)

I should probably mention that the updateScore function is being called outside the file. As I said, the function itself seems to work fine as the print statements indicate.

here is where i'm using the widget (this is the entire file):

class RecordingPage extends StatefulWidget {
  RecordingPage({Key key}) : super(key: key);

  _RecordingPageState createState() => _RecordingPageState();
}

class _RecordingPageState extends State<RecordingPage> {
  final GlobalKey<MeterState> meterState = GlobalKey<MeterState>();
  int yes = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        floatingActionButton: Container(
            width: this.yes * 10.0,
            child: FittedBox(
                child: FloatingActionButton(
              onPressed: null,
              backgroundColor: Colors.white,
            ))),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
        backgroundColor: Colors.white,
        appBar: offTopTitle,
        body: Column(
          children: <Widget>[
            Row(children: [
              Expanded(
                child: FlatButton(
                  child: Text("Go To Websocket"),
                  color: Colors.blue,
                  onPressed: () {
                    Navigator.pushNamed(context, WebsocketRoute);
                  },
                ),
              ),
            ]),
            Container(
              height: MediaQuery.of(context).size.height / 4,
              child: Image.asset('assets/placeholderWave.gif'),
            ),
            Container(
              margin: EdgeInsets.only(top: 5),
              height: MediaQuery.of(context).size.height / 4,
              child: Meter(key: meterState),
            ),
            Recorder((isOnTopic) {
              meterState.currentState.updateScore(isOnTopic);
            }),
          ],
        ),
        bottomNavigationBar: AppBarBuilder());
  }
}

Solution

  • After toying around with the package in a new flutter project I have been unable to get it to update after creation using many different ways and after looking at all available documentation for the package at this time, I am not sure it is meant to be used in this way. There are no examples of changing the gauge after it is built so it appears to be an immutable widget.

    I did some digging and the syncfusion_flutter_gauges looks like a promising alternative and this article goes over how to do what I think you are attempting in your project. Hope it helps