Если я правильно понимаю, вы хотите уведомить StatefullWidget
от другого StatefullWidget
.Существует несколько подходов к этому, но поскольку вы упомянули Streams
, я постараюсь опубликовать пример и немного пояснить этот сценарий.
Таким образом, в принципе, вы можете рассматривать потоки как связанные каналык крану на одном конце, а на другом конце он добавляется в чашку (конец может быть разбит на несколько концов и помещен в несколько чашек, «трансляция потоков»).
Теперь чашка является слушателем (подписчик) и ждет, пока вода упадет через трубу.
Смеситель является излучателем, и он будет испускать капли воды при открытии смесителя.
Смеситель можно открывать, когда другой конец помещается в чашку, это интеллектуальный смеситель с несколькими охлаждающими датчиками (излучатель начнет излучать события, когда «обнаруживается подписчик»).
Капли - это реальные события, которые происходят в приложении.
Также вы должны помнить, чтобы закрыть кран, чтобы избежать массовой утечки из чашки на кухонный пол. (Вы должны отменить подписчиковкогда вы закончите обработку событий, чтобы избежать утечки).
Теперь для вашего конкретного случая приведем фрагмент кода, который как бы иллюстрирует приведенную выше метафору:
class ThePannel extends StatefulWidget { // this is the cup
final Stream<bool> closeMeStream; // this is the pipe
const ThePannel({Key key, this.closeMeStream}) : super(key: key);
@override
_ThePannelState createState() => _ThePannelState(closeMeStream);
}
class _ThePannelState extends State<ThePannel> {
bool _closeMe = false;
final Stream<bool> closeMeStream;
StreamSubscription _streamSubscription;
_ThePannelState(this.closeMeStream);
@override
void initState() {
super.initState();
_streamSubscription = closeMeStream.listen((shouldClose) { // here we listen for new events coming down the pipe
setState(() {
_closeMe = shouldClose; // we got a new "droplet"
});
});
}
@override
void dispose() {
_streamSubscription.cancel(); // THIS IS QUITE IMPORTANT, we have to close the faucet
super.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
SomeWidgetHere(shouldClose: _closeMe),
RaisedButton(
onPressed: () {
setState(() {
_closeMe = true;
});
},
)
],
);
}
}
class SomeWidgetThatUseThePreviousOne extends StatefulWidget { // this one is the faucet, it will emit droplets
@override
_SomeWidgetThatUseThePreviousOneState createState() =>
_SomeWidgetThatUseThePreviousOneState();
}
class _SomeWidgetThatUseThePreviousOneState
extends State<SomeWidgetThatUseThePreviousOne> {
final StreamController<bool> thisStreamWillEmitEvents = StreamController(); // this is the end of the pipe linked to the faucet
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
ThePannel(closeMeStream: thisStreamWillEmitEvents.stream), // we send the other end of the pipe to the cup
RaisedButton(
child: Text("THIS SHOULD CLOSE THE PANNEL"),
onPressed: () {
thisStreamWillEmitEvents.add(true); // we will emit one droplet here
},
),
RaisedButton(
child: Text("THIS SHOULD OPEN THE PANNEL"),
onPressed: () {
thisStreamWillEmitEvents.add(false); // we will emit another droplet here
},
)
],
);
}
@override
void dispose() {
thisStreamWillEmitEvents.close(); // close the faucet from this end.
super.dispose();
}
}
Я надеюсь, что моя аналогияпоможет вам немного понять концепцию потоков.