Почему StreamBuilder использует initialData несколько раз, а не последний снимок?

Я, наверное, просто неправильно понимаю поток дротика, но когда я делаю это:

TabBarView(
  children: [
    ...
    StreamBuilder(
      builder(context, url){ 
        ...
        print(url);
        ...
      },
      stream: () async* { ... }().asBroadcastStream(),
      initialData: 'Dope',
    )
    ...
  ]
)

Я получаю странное поведение при рендеринге StreamBuilder с помощью TabBarView.

Во-первых, мне нужно использовать asBroadcastStream (), иначе я получу:

Плохое состояние: поток уже прослушан

что я признаю, это плохое решение.

Но пока решение работает, возврат к StreamBuilder в TabBarView теперь приведет к повторному построению с повторным использованием initialData, а не последнего моментального снимка потока. Вот результат печати при двойном возврате на вкладку:

I / flutter (14541): допинг
I / flutter (14541): правильный URL
I / flutter (14541): допинг
I / flutter (14541): допинг

Я представляю, что обе проблемы связаны, но я не понимаю, почему StreamBuilder повторно использует async * и initialData


person Nahej    schedule 31.03.2020    source источник
comment
Обертывание StreamBuilder в Builder устраняет вторую проблему, не знаю, почему ...   -  person Nahej    schedule 01.04.2020


Ответы (1)


Вероятно, ваш виджет воссоздается, преобразуйте его в StatefulWidget и замените dispose() print(disposed) внутри него для подтверждения.

Кроме того, внутри StreamBuilder напечатайте snapshot.connectionState, ваш connectionState, вероятно, изменится с waiting на active, и поэтому построитель вызывается с initalData.

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

person Michel Feinstein    schedule 31.03.2020
comment
печать connectionState подтвердила, что поток выполнял waiting - ›active для первого рендеринга и только waiting для дальнейшего рендеринга - person Nahej; 01.04.2020
comment
Так что, если это отвечает на ваш вопрос, не забудьте принять его и проголосовать за него. - person Michel Feinstein; 01.04.2020