簡體   English   中英

flutter 中的相同 StreamBuilders,一個正在工作,另一個返回 null

[英]Identical StreamBuilders in flutter, one is working other returns null

我在兩個不同的小部件中有兩個相同的 stream 構建器。 一個工作,而另一個不接收數據。 這是小部件樹。

在此處輸入圖像描述

這是StreamBuilder

StreamBuilder<AudioPlayerState>(
    stream: _playbackProvider.playbackState,
    builder: (context, snapshot) {
      IconData _playbackButton = Icons.play_circle_filled;

         if (snapshot.hasData) {
             if (snapshot.data == AudioPlayerState.PLAYING) {
                  _playbackButton = Icons.pause_circle_filled;
             } else {
                  _playbackButton = Icons.play_circle_filled;
             }
         }

        return OutlineButton(
             onPressed: () {
               _playButtonClicked(snapshot.data);
             },
             child: Icon(_playbackButton),
             shape: CircleBorder(),
        );
}),

這是他們都在聽的 stream:

Stream<AudioPlayerState> get playbackState {
    return _audioPlayer.onPlayerStateChanged; // using onPlayerStateChanged stream provided by audioplayers plugin.
}

這個 stream 可以由更改通知提供程序在這兩個小部件(腳手架)中訪問。 音頻播放器包含在 ChangeNotifier class 中。

class PlaybackProvider with ChangeNotifier {
  String _path;
  AudioPlayer _audioPlayer;

  PlaybackProvider() {
    _audioPlayer = AudioPlayer();
    _audioPlayer.setReleaseMode(ReleaseMode.STOP);
    _audioPlayer.notificationState = AudioPlayerState.STOPPED;
  }

  Stream<Duration> get playbackPosition { // this stream is also working fine in the first screen (widget)
    return _audioPlayer.onAudioPositionChanged;
  }

  Stream<AudioPlayerState> get playbackState {
    return _audioPlayer.onPlayerStateChanged;
  }

//other methods
}

然后將更改通知器提供給這些小部件中的每一個。

final _playbackProvider = Provider.of<PlaybackProvider>(context);

和主要的function,

void main() {
  runApp(MultiProvider(providers: [
    ChangeNotifierProvider(create: (_) => PlaylistProvider()),
    ChangeNotifierProvider(create: (_) => PlaybackProvider()),
  ], child: MyApp()));
}
Stream<Duration> get playbackPosition { // this stream is also working fine in the first screen (widget)
    return _audioPlayer.onAudioPositionChanged;
  }

您確定 _audioPlayer.onAudioPositionChanged 是一個 BroadcastStream 還是它返回相同的 Strem 實例,可能是每次調用它時 getter 返回不同的實例,確保您具有相同值的一種方法是創建一個 StreamProvider,然后在樹中使用它

void main() {
  runApp(MultiProvider(providers: [
    ChangeNotifierProvider(create: (_) => PlaylistProvider()),
    ChangeNotifierProvider(create: (_) => PlaybackProvider()),
    StreamProvider<AudioPlayerState>(create: (context) => Provider.of<PlaybackProvider>(context, listen: false).playbackState)
  ], child: MyApp()));
}

然后在每個小部件中而不是 StreamBuilder 只使用消費者

return OutlineButton(
  onPressed: () => _playButtonClicked(snapshot.data),
  child: Consumer<AudioPlayerState>(
    builder: (context, data, _) {
      if(data  == AudioPlayerState.PLAYING) return Icon(Icons.pause_circle_filled);
      return Icon(Icons.play_circle_filled);
    }
  ),
  shape: CircleBorder(),
);

您的代碼和邏輯沒有錯,但是如果您使用提供者,最好使用它提供的所有類型的提供者(諷刺地)對您有利。 如果您想繼續使用 StreamBuilder,那也可以,但是如果沒有看到您的AudioPlayer class 代碼,則很難確定返回_audioPlayer.onAudioPositionChanged的內容,如果它是一個簡單的 stream,您是在重新創建它的廣播方法嗎?使用 asBroadCast 方法)等?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM