81 votes

Flutter: mauvais état: le flux a déjà été écouté

 
    class MyPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return DefaultTabController(
          length: 2,
          child: new Scaffold(
            appBar: TabBar(
              tabs: [
                Tab(child: Text("MY INFORMATION",style: TextStyle(color: Colors.black54),)),
                Tab(child: Text("WEB CALENDER",style: TextStyle(color: Colors.black54),)),
              ],
            ),
            body:PersonalInformationBlocProvider(
              movieBloc: PersonalInformationBloc(),
              child: TabBarView(
                children: [
                  MyInformation(),
                  new SmallCalendarExample(),
                ],
              ),
            ),
          ),
        );
      }
    }

    class MyInformation extends StatelessWidget{
      // TODO: implement build
      var deviceSize;

      //Column1
      Widget profileColumn(PersonalInformation snapshot) => Container(
        height: deviceSize.height * 0.24,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                Container(
                  decoration: BoxDecoration(
                    borderRadius:
                    new BorderRadius.all(new Radius.circular(50.0)),
                    border: new Border.all(
                      color: Colors.black,
                      width: 4.0,
                    ),
                  ),
                  child: CircleAvatar(
                    backgroundImage: NetworkImage(
                        "http://www.binaythapa.com.np/img/me.jpg"),
                    foregroundColor: Colors.white,
                    backgroundColor: Colors.white,
                    radius: 40.0,
                  ),
                ),
                ProfileTile(
                  title: snapshot.firstName,
                  subtitle: "Developer",
                ),
                SizedBox(
                  height: 10.0,
                ),
              ],
            )
          ],
        ),
      );
      Widget bodyData(PersonalInformation snapshot) {
        return SingleChildScrollView(
            child: Column(
              children: <Widget>[
                profileColumn(snapshot)
              ],
            ),
        );
      }


      @override
      Widget build(BuildContext context) {
        final personalInformationBloc = PersonalInformationBlocProvider.of(context);

        deviceSize = MediaQuery.of(context).size;
        return StreamBuilder(
            stream: personalInformationBloc.results,
            builder: (context,snapshot){
              if (!snapshot.hasData)
                return Center(
                  child: CircularProgressIndicator(),
                );
              return bodyData(snapshot.data);
            }
        );
      }
    }


 

J'utilise Bloc Pattern pour récupérer les données de l'API Rest (juste appelé objet entier de json et nom d'utilisateur analysé uniquement). La page se compose de deux onglets MyIformation et SmallCalendar. Lorsque l'application s'exécute, les données sont récupérées correctement et tout va bien. Lorsque je vais à l'onglet deux et que je reviens à l'onglet un, tous les écrans de l'onglet un vont au rouge, indiquant une erreur: Bad state: Stream has already been listened to.

99voto

amenbo Points 363

Vous devez utiliser ce qui suit.

 StreamController<...> _controller = StreamController<...>.broadcast();
 

42voto

Rémi Rousselet Points 45139

La forme la plus courante de Stream peut être écouté qu'une seule fois à un moment. Si vous essayez d'ajouter plusieurs auditeurs, qu'il va jeter

Mauvais état: cours d'eau a déjà été écouté

Pour éviter cette erreur, exposer une diffusion Stream. Vous pouvez convertir vos flux pour une diffusion à l'aide de myStream.asBroadcastStream

Ce qui doit être fait à l'intérieur de votre classe qui exposent Stream. Pas en tant que paramètre de l' StreamBuilder. Depuis asBroadcastStream en interne écouter le flux d'origine afin de générer de l'émission, cela implique que vous ne pouvez pas appeler cette méthode deux fois sur le même cours d'eau.

36voto

Andrey Gordeev Points 6348

Vous pouvez utiliser broadcast, ce qui permet d'écouter les flux plus d'une fois, mais il empêche aussi de l'écoute des événements passés:

Les flux de diffusion ne sont pas de la mémoire tampon des événements lorsqu'il n'y a pas d'auditeur.

Une meilleure option est d'utiliser BehaviorSubject de rxdart package de la classe en tant que StreamController. BehaviorSubject est:

Un spécial StreamController qui capture le dernier élément qui a été ajouté à la manette, et émet que comme le premier élément à n'importe quel nouveau port d'écoute.

L'utilisation est aussi simple que:

StreamController<...> _controller = BehaviorSubject();

21voto

Samer s Salib Points 789

Dans mon cas, j'obtenais cette erreur car la même ligne de code myStream.listen() était appelée deux fois dans le même widget sur le même flux. Apparemment, ce n'est pas autorisé!

Ce qui a résolu cela pour moi, c'est de créer un contrôleur de flux en tant que contrôleur de flux de diffusion:

 var myStreamController = StreamController<bool>.broadcast();
 

ET

utiliser le flux comme flux de diffusion:

 myStreamController.stream.asBroadcastStream().listen(onData);
 

12voto

BINAY THAPA MAGAR Points 1005

Le problème était dû au fait de ne pas disposer les contrôleurs en bloc.

   void dispose() {
    monthChangedController.close();
    dayPressedController.close();
    resultController.close();
  }
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X