如何从父小部件在子状态小部件内运行函数? [英] How to run a function inside a child stateful widget from parent widget?
问题描述
我试图通过在该孩子的父母的父母中点击按钮在StateFul小部件内的两层内运行该函数(带有自变量)( 构建完所有小部件之后,而不是在构造函数之内)。就像下面的图片一样:
更多细节是我创建了Carousal里面有卡片,
在首页屏幕内:
///。 ..Inside Homepage屏幕级别0
RaisedButton(
子级:Text('BLoC中的更新值'),
onPressed:(){
bloc.changeSelectedState(isSel) ;
},
),
// ...
在BLoC内部:
类Bloc {
最终的BehaviorSubject< bool> _isSelectedStreamController = BehaviorSubject< bool>();
//从流
中检索数据Stream< bool>得到isSelectedStream => _isSelectedStreamController.stream;
//将数据添加到流
Function(bool)get changeSelectedState => _isSelectedStreamController.sink.add;
void dispose(){
_isSelectedStreamController.close();
}
}
final bloc = Bloc();
在任何级别的任何小部件内,只要它可以到达整个集团即可:
//这在两级向下的有状态小部件内。.
StreamSubscription isSelectedSubscription;
Stream isSelectedStream = bloc.isSelectedStream;
isSelectedSubscription = isSelectedStream.listen((value){
//设置标志,然后设置setState以便显示边框。
setState((){
isSelected = value;
});
});
// ...其他代码
@override
Widget build(BuildContext context){
return Container(
装饰:isSelected
?BoxDecoration(
颜色:Colors.deepOrangeAccent,
边框:Border.all(
宽度:2,
颜色:Colors.amber,
),
)
:null,
// ...其他代码
);
}
所以我小部件的新设计将BLoC作为主要内容
and ...以灵活,简洁的代码和体系结构像魅力一样工作^^
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). just like in the image below:
More details is that I created a Carousal which has Cards inside, published here.
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.
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:
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?".
I appreciate any help. thanks a lot.
I was able to solve that challenge using the BLoC & Stream & StreamSubscription, see the image below:
Inside the Homepage screen:
///...Inside Homepage screen level-0
RaisedButton(
child: Text('Update value in the BLoC'),
onPressed: () {
bloc.changeSelectedState(isSel);
},
),
//...
inside the 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:
and...works like a charm with flexible and clean code and architecture ^^
这篇关于如何从父小部件在子状态小部件内运行函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!