a_str0
a_str0

Reputation: 5

Wait the data and the use it in the gui FLUTTER

I have a slider that uses a value to render himself, it start rendering after I hit a button but the first time I render it, it gives me an error and then starts working properly. This is the error:

The getter 'inSeconds' was called on null. Receiver: null Tried calling: inSeconds

This is the widget that uses the data:

child: Consumer<MyAudio>(
                        builder: (context, audioPlayer, child) =>
                            SleekCircularSlider(
                          appearance: CircularSliderAppearance(
                            customWidths: CustomSliderWidths(
                              progressBarWidth: 2.0,
                              trackWidth: 1.0,
                              handlerSize: 1.0,
                              shadowWidth: 1.0,
                            ),
                            infoProperties: InfoProperties(
                              modifier: (value) => '',
                            ),
                            customColors: CustomSliderColors(
                              trackColor: Colors.grey,
                              progressBarColor: Colors.black,
                            ),
                            size: 4.0,
                            angleRange: 360,
                            startAngle: -90.0,
                          ),
                          min: 0.0,
                          max: audioPlayer.songLength.inSeconds.toDouble(),
                          initialValue:
                              audioPlayer.position.inSeconds.toDouble(),
                        ),
                      ),
                    ),

And this is the function that gives me the values songLength and position:

class MyAudio extends ChangeNotifier {
  Duration songLength;
  Duration position;

  AudioPlayer _player = AudioPlayer();
  AudioCache cache;

  MyAudio() {
    initAudio();
  }

  initAudio() {
    cache = AudioCache(fixedPlayer: _player);
    _player.onDurationChanged.listen((Duration d) {
      songLength = d;
      notifyListeners();
    });
    _player.onAudioPositionChanged.listen((Duration p) {
      position = p;
      notifyListeners();
    });

I think I should use an async function, what do you think? If you need more code here's my github repo with all the files: https://github.com/astroxd/sputofy_mobile/tree/main/sputofy_2 the slider is in /lib/miniPlayer and the values are in /lib/model/audioPlayer

Upvotes: 0

Views: 85

Answers (1)

Frank Moreno
Frank Moreno

Reputation: 344

The problem is that when the widget is built for first time, the audioPlayer.songLength and audioPlayer.position are null despite audioPlayer is non-null.

In this fragment of code you define a pair of listeners, but the callbacks are called after the first build.

_player.onDurationChanged.listen((Duration d) {
      songLength = d;
      notifyListeners();
    });
    _player.onAudioPositionChanged.listen((Duration p) {
      position = p;
      notifyListeners();
    });

Then, a solution can be the following:

child: Consumer<MyAudio>(
  builder: (context, audioPlayer, child) => SleekCircularSlider(
    appearance: CircularSliderAppearance(
      customWidths: CustomSliderWidths(
        progressBarWidth: 2.0,
        trackWidth: 1.0,
        handlerSize: 1.0,
        shadowWidth: 1.0,
      ),
      infoProperties: InfoProperties(
        modifier: (value) => '',
      ),
      customColors: CustomSliderColors(
        trackColor: Colors.grey,
        progressBarColor: Colors.black,
      ),
      size: 4.0,
      angleRange: 360,
      startAngle: -90.0,
    ),
    min: 0.0,
    max: audioPlayer.songLength?.inSeconds?.toDouble() ?? 0.0,
    initialValue: audioPlayer.position?.inSeconds?.toDouble() ?? 0.0,
  ),
)

Or maybe use a loader instead.

Upvotes: 1

Related Questions