web-dev-qa-db-fra.com

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


 La classe MyPage étend StatelessWidget {
 @passer outre
 Construction du widget (contexte BuildContext) {
 defaultTabController (
 longueur: 2, 
 enfant: nouveau Scaffold (
 appBar: Tab. Barre. 
 tabs: [
 tab (enfant: Text ("MES INFORMATIONS"), style: TextStyle (color : Colors.black54),)), 
 (Enfant: Text ("WEB CALENDER", style: TextStyle (color: Colors.black54),)), 
], 
, 
 body: PersonalInformationBlocProvider (
 movieBloc: PersonalInformationBloc (), 
 child: TabBarView (
 children: [
 MyInformation (), 
 new SmallCalendarExample (), 
)., 
) , 
), 
), 
); 
 } 
 } 

 La classe MyInformation étend StatelessWidget {
 // TODO: implémenter la construction 
 var deviceSize; 

 //Colonne1
 Widget profileColumn (PersonalInformation snapshot) => Conteneur (
 Height: deviceSize.height * 0.24, 
 Child: Column (
 MainAxisAlignment: MainAxisAlignment.center, 
 Children: [
 Row:. . mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
 enfants: [
 Conteneur (
 décoration: BoxDecoration (
 borderRadius: 
 nouveau BorderRadius.all (nouveau Radius.circular (50.0)), 
 border: new Border.all (
 couleur: Colors.black, 
 width: 4.0, 
), 
), 
 child: CircleAvatar (
 backgroundImage: NetworkImage (
 "http://www.binaythapa.com.np/img/me.jpg"),
 foregroundColor: Colors.white, 
 backgroundColor: Couleurs.white, 
 rayon: 40,0, 
 ), 
 ), 
 ProfileTile (
 Title: snapshot.firstName, 
 Sous-titre: "Developer", 
), 
 SizedBox (
 Hauteur: 10.0, 
), 
 ], 
 ) 
 ], 
 ), 
 ); 
 Widget bodyData (instantané PersonalInformation) {
 return SingleChildScrollView (
 child: Column (
 children: [
 profileColumn (instantané) 
], 
), 
); 
 } 


 @passer outre
 Construction du widget (contexte BuildContext) {
 final personalInformationBloc = PersonalInformationBlocProvider.of (contexte); 

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


J'utilise Bloc Pattern pour récupérer des données à partir de Rest API (simplement appelé objet entier à partir de json et nom d'utilisateur analysé uniquement). La page se compose de deux onglets MyIformation et SmallCalendar. Lorsque l'application est exécutée, les données sont récupérées correctement et tout va bien. Lorsque je vais à l'onglet 2 et que je retourne à l'onglet 1, tous les écrans de l'onglet 1 deviennent rouges et affichent l'erreur: Bad state: Stream has already been listened to.

7
Mercy peka

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

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

La forme la plus commune de Stream ne peut être écoutée qu'une fois à la fois. Si vous essayez d’ajouter plusieurs auditeurs, cela jettera 

Mauvais état: le flux a déjà été écouté

Pour éviter cette erreur, exposez un broadcast Stream. Vous pouvez convertir votre flux en diffusion à l'aide de myStream.asBroadcastStream

Cela doit être fait dans votre classe qui expose Stream. Pas comme paramètre de StreamBuilder. Étant donné que asBroadcastStream écoute en interne le flux d'origine pour générer celui de diffusion, vous ne pouvez pas appeler cette méthode deux fois sur le même flux.

5
Rémi Rousselet

Vous devriez utiliser ce qui suit.

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

J'ai eu le même problème lorsque j'ai utilisé un résultat de Observable.combineLatest2 pour StreamBuilder dans Drawer:

flutter: Mauvais état: le flux a déjà été écouté.

Quant à moi, la meilleure solution a ajouté le résultat de cette combinaison à un nouveau BehaviorSubject et à un nouveau.

N'oubliez pas d'écouter le vieil !!!

class VisitsBlocc extends Object {
    Map<Visit, Location> visitAndLocation;

    VisitsBloc() {
        visitAndLocations.listen((data) {
            visitAndLocation = data;
        });
    }

    final _newOne = new BehaviorSubject<Map<Visit, Location>>();

    Stream<Map<Visit, Location>> get visitAndLocations => Observable.combineLatest2(_visits.stream, _locations.stream, (List<vis.Visit> visits, Map<int, Location> locations) {
        Map<vis.Visit, Location> result = {};

        visits.forEach((visit) {
            if (locations.containsKey(visit.skuLocationId)) {
                result[visit] = locations[visit.skuLocationId];
            }
        });

        if (result.isNotEmpty) {
            _newOne.add(result);
        }
    });
}

Je n'ai pas utilisé .broadcast car cela a ralenti mon interface utilisateur. 

0
Serhii