重新打开使用StreamBuilder的ExpansionTile时,Stream处于错误状态

时间:2019-02-12 23:44:55

标签: dart flutter

第一次打开ExpansionTitle,一切都很好。缩小和扩展它之后,我收到一个已经听到的“错误状态”流,错误。我尝试将流作为广播返回,但是在最小化并重新打开后,快照为空。我不太确定将ExpansionTitle与流一起使用的正确技术是什么。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
  return MaterialApp(
  title: 'Flutter Demo',
  home: MyHomePage(title: 'Flutter Demo Home Page'),
 );
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;

@override
 _MyHomePageState createState() => _MyHomePageState();
  }
   class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
  appBar: AppBar(
    title: Text(widget.title),
  ),
  body: Center(
    child: StreamBuilder(
        stream: _genres(),
        builder:
            (BuildContext context, AsyncSnapshot<List<String>> snapshot) {
          print("snap:  ${snapshot.data}");
          if (snapshot.hasData) {
            return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (BuildContext context, int index) {


              return ExpansionTile(
                title: Text(snapshot.data[index]),
                children: <Widget>[
                  StreamBuilder(
                    stream: _moviemap(index + 1),
                    builder: (BuildContext context, AsyncSnapshot snapshot) {
                      if (!snapshot.hasData)
                        return Text('No data');


                      List<Widget> items = [];
                      for(String name in snapshot.data) {
                        items.add(
                          ListTile(
                            title: Text(name),
                          )
                        );
                      }

                      return Column(children: items,);
                    },
                  ),
                ],
              );
            });
          } else {
            return Container();
          }
        }),
  ),
 );
}
   Stream<List<String>> _genres() async* {
     yield ['Horror', 'Comedy', 'Drama'];
   }

   Stream<List<String>> _moviemap(int which) async* {
   if (which == 1) {
      yield ['Saw', 'Scary Movie'];
    } else if (which == 2) {
      yield ['Grown ups', 'Grown ups 2', 'Paul Blart'];
    } else {
      yield ['Green Onions', 'Spring Breakers'];
    }
 }
 }

1 个答案:

答案 0 :(得分:0)

这是因为以下原因。

  1. StreamBuilder永久监听从_moviemap的{​​{1}}到StreamBuilder的相同流(在这种情况下为initState())。
  2. dispose()打开和关闭时,它将重建ExpansionTile的新children。并且StreamBuilder尝试听StreamBuilder。旧的_moviemap当时尚未完成dispose()。
  3. 同一流(StreamBuilder)不允许收听多次。
  4. 所以坠毁了。

因此,您应该交换_moviemap的位置和StreamBuilder的位置以一次侦听流(ExpansionTile)。祝你好运!

示例代码:

_moviemap