Поток уже прослушан, ошибка после смены экрана - PullRequest
1 голос
/ 15 июня 2019

Я применяю шаблон Bloc в своем приложении, и у меня возникли проблемы при смене экрана с помощью нижней навигации.

Я попытался выполнить потоковую трансляцию, однако после изменения экрана данные исчезли.

Вот мой класс Home, он представляет домашний экран.

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final DepartmentBloc departmentBloc = BlocProvider.getBloc<DepartmentBloc>();
  final PromotionProductBloc promotionProductBloc = BlocProvider.getBloc<PromotionProductBloc>();

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      physics: BouncingScrollPhysics(),
      child: SafeArea(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            CustomText(
              text: "Promoções",
              fontSize: 20.0,
              padding: EdgeInsets.only(left: 12.0),
            ),
            StreamBuilder(
              stream: promotionProductBloc.outPromotionProducts,
              builder: (context, snapshot) {
                if (snapshot.hasData)
                  return Container(
                    height: 230.0,
                    child: ListView.builder(
                      padding: EdgeInsets.only(
                          left: 12.0, right: 12.0, bottom: 10.0),
                      itemBuilder: (context, index) {
                        return PromotionProductCard(snapshot.data[index]);
                      },
                      itemCount: snapshot.data.length,
                      scrollDirection: Axis.horizontal,
                      physics: BouncingScrollPhysics(),
                    ),
                  );
                else
                  return Container(
                    height: 200.0,
                  );
              },
            ),
            CustomText(
              text: "Categorias",
              fontSize: 20.0,
              padding: EdgeInsets.only(left: 12.0, top: 20.0, bottom: 10.0),
            ),
            StreamBuilder(
              stream: departmentBloc.outDepartments,
              builder: (context, snapshot) {
                if (snapshot.hasData)
                  return Container(
                    height: 120.0,
                    child: ListView.builder(
                      padding: EdgeInsets.only(left: 12.0, right: 12.0),
                      itemBuilder: (context, index) {
                        return CategoryCard(snapshot.data[index]);
                      },
                      itemCount: snapshot.data.length,
                      scrollDirection: Axis.horizontal,
                      physics: BouncingScrollPhysics(),
                    ),
                  );
                else
                  return Container(
                    height: 100.0,
                  );
              },
            ),
          ],
        ),
      ),
    );
  }

Вот класс, который получает доступ к Сервису для получения данных и открывает выход в Stream.

class DepartmentBloc extends BlocBase {

  DepartmentService departmentService;

  List<Department> departments;

  final StreamController<List<Department>> _departmentController = StreamController<List<Department>>();
  Stream<List<Department>> get outDepartments => _departmentController.stream;

  DepartmentBloc() {
    departmentService = DepartmentService();
    getAll();
  }

  void getAll() async {
    departments =  await departmentService.getAll();
    _departmentController.sink.add(departments);
  }

  @override
  void dispose() {
    _departmentController.close();
    super.dispose();
  }
}

PromotionProductBloc - это то же самое, что и DepartmentBloc, оно только меняет доступ к Сервису.

Я использую Навигацию снизу, после перехода на другой экран и возврата появляется следующая ошибка: Поток уже прослушан.

1 Ответ

0 голосов
/ 15 июня 2019

Попробуйте

  final StreamController<List<Department>> _departmentController = StreamController.broadcast<List<Department>>();

Похоже, вы используете один контроллер потока подписки.Их можно слушать только один раз.Преимущество их заключается в том, что первый слушатель получит событие, которое было отправлено, прежде чем подписаться на него.Широковещательные потоки не гарантируют такого поведения, но на них можно подписаться несколько раз.

...