[英]How to run a function inside a child stateful widget from parent widget?
I am trying to run a function(with arguments) inside two-levels down StateFul widget , by clicking a button in the parent of the parent of that child( after having all widgets built, so not inside the constructor ).我试图通过单击该子级的父级的父级中的按钮(在构建所有小部件之后,而不是在构造函数内)在两级下 StateFul 小部件内运行一个函数(带参数)。 just like in the image below:就像下图一样:
More details is that I created a Carousal which has Cards inside, published here .更多细节是我创建了一个里面有卡片的 Carousal,在这里发布。
I created it with StreamBuilder in mind(this was the only use case scenario that I used it for so far), so once the stream send an update, the builder re-create the whole Carousal, so I can pass the SELECTED_CARD_ID to it.我在创建它时考虑到了 StreamBuilder(这是迄今为止我使用它的唯一用例场景),因此一旦流发送更新,构建器就会重新创建整个 Carousal,因此我可以将 SELECTED_CARD_ID 传递给它。
But now I need to trigger the selection of the carousal's Cards programmatically, or in another word no need for two construction based on the snapshot's data like this:但是现在我需要以编程方式触发 carousal 卡片的选择,或者换句话说,不需要基于快照的数据进行两次构建,如下所示:
return StreamBuilder(
stream: userProfileBloc.userFaviourateStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return SelectableCarousal(
selectedId: snapshot.data.toInt(),
onTap: //Update the stream
//some props...,
);
} else {
return SelectableCarousalLoading(
selectedId: null,
onTap: //Update the stream
//some props...,
);
}
},
);
But instead, I'm trying to have something like this so I can use it for others use cases:但是相反,我正在尝试使用这样的东西,以便我可以将它用于其他用例:
Widget myCarousal = SelectableCarousal(
selectedId: null,
onTap: //Update the stream
//some props...,
);
return StreamBuilder(
stream: userProfileBloc.userFaviourateStream,
builder: (context, snapshot) {
// Then when data ready I can update
// the selection by calling two-level down function
if (snapshot.hasData) {
myCarousal.selectById(3);
}
// Build same carousal in all cases.
return myCarousal;
},
);
so this led me to my original question " How to run a function(with arguments) inside two-levels down StateFul widget? ".所以这让我想到了我最初的问题“如何在 StateFul 小部件的两级内运行函数(带参数)? ”。
I appreciate any help.我很感激任何帮助。 thanks a lot.多谢。
I was able to solve that challenge using the BLoC & Stream & StreamSubscription , see the image below:我能够使用BLoC & Stream & StreamSubscription解决这个挑战,见下图:
Inside the Homepage screen:在主页屏幕内:
///...Inside Homepage screen level-0
RaisedButton(
child: Text('Update value in the BLoC'),
onPressed: () {
bloc.changeSelectedState(isSel);
},
),
//...
inside the BLoC:在 BLoC 内部:
class Bloc {
final BehaviorSubject<bool> _isSelectedStreamController = BehaviorSubject<bool>();
// Retrieve data from stream
Stream<bool> get isSelectedStream => _isSelectedStreamController.stream;
// Add data to stream
Function(bool) get changeSelectedState => _isSelectedStreamController.sink.add;
void dispose() {
_isSelectedStreamController.close();
}
}
final bloc = Bloc();
Inside any widget in any level as long as it can reach the bloc:在任何级别的任何小部件内,只要它可以到达该集团:
// This inside the two-levels down stateful widget..
StreamSubscription isSelectedSubscription;
Stream isSelectedStream = bloc.isSelectedStream;
isSelectedSubscription = isSelectedStream.listen((value) {
// Set flag then setState so can show the border.
setState(() {
isSelected = value;
});
});
//...other code
@override
Widget build(BuildContext context) {
return Container(
decoration: isSelected
? BoxDecoration(
color: Colors.deepOrangeAccent,
border: Border.all(
width: 2,
color: Colors.amber,
),
)
: null,
//...other code
);
}
so the new design of my widget includes the BLoC as a main part of it, see the image:所以我的小部件的新设计包括 BLoC 作为它的主要部分,请参见图像:
and...works like a charm with flexible and clean code and architecture ^^和...工作就像一个魅力与灵活和干净的代码和架构^^
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.