这是该场景的简化版本:
class ParentWdiegt extends StatelessWidget{
//
//
floatinActionButton: FloatingActionButtonWidget(onPressed:()=>CustomWidgetState.someMethod(someValue))
//
//somewhere in the ParentWidget tree
child: CustomWidget() //is stateful
}
CustomWidgetState
class CustomWidgetState extends State<CustomWidget>{
//trigger this function when FAB is pressed in parent widget
someMethod(SomeValue) {//}
}
在没有使用someMethod
的情况下按下FAB时,有什么方法可以在要触发的状态对象中公开InheritedWidget
吗?
答案 0 :(得分:19)
虽然GlobalKey
允许轻松访问任何小部件的状态;躲开它。
窗口小部件应该不直接与其他窗口小部件交互。这是Flutter的核心原则之一。
Flutter使用反应式编程。小部件通过提交事件与彼此通信的位置。而不是直接编辑所需的小部件。
显而易见的好处是小部件保持独立。并且可能有数十个小部件可以使用相同的原则相互通信。
我已经就如何使两个不同的小部件共享一个共同的可编辑值做了一个示例here。
如果您想要调用方法,则使用相同的原则:小部件之间共享Listenable
或Stream
。但是没有使用AnimatedWidget
或StreamBuilder
进行收听。
相反,我们将手动进行监听(这需要更多的样板)来触发自定义功能。
以下是使用Stream
的示例。
import 'dart:async';
import 'package:flutter/material.dart';
class ParentWidget extends StatefulWidget {
@override
_ParentWidgetState createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
final changeNotifier = new StreamController.broadcast();
@override
void dispose() {
changeNotifier.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
new AnotherWidget(
shouldTriggerChange: changeNotifier.stream,
),
new RaisedButton(
child: new Text("data"),
onPressed: () => changeNotifier.sink.add(null),
)
],
);
}
}
class AnotherWidget extends StatefulWidget {
final Stream shouldTriggerChange;
AnotherWidget({@required this.shouldTriggerChange});
@override
_AnotherWidgetState createState() => _AnotherWidgetState();
}
class _AnotherWidgetState extends State<AnotherWidget> {
StreamSubscription streamSubscription;
@override
initState() {
super.initState();
streamSubscription = widget.shouldTriggerChange.listen((_) => someMethod());
}
@override
didUpdateWidget(AnotherWidget old) {
super.didUpdateWidget(old);
// in case the stream instance changed, subscribe to the new one
if (widget.shouldTriggerChange != old.shouldTriggerChange) {
streamSubscription.cancel();
streamSubscription = widget.shouldTriggerChange.listen((_) => someMethod());
}
}
@override
dispose() {
super.dispose();
streamSubscription.cancel();
}
void someMethod() {
print('Hello World');
}
@override
Widget build(BuildContext context) {
return Container();
}
}
在此示例中,只要执行someMethod
实例化的AnotherWidget
上的点击,就会调用RaisedButton
_ParentWidgetState
。
答案 1 :(得分:2)
您可以使用GlobalKey
:
// some global place
final customWidgetKey = new GlobalKey<CustomWidgetState>();
...
// import the file with "customWidgetKey"
new CustomWidget(key: customWidetKey, ...)
...
// import the file with "customWidgetKey"
floatinActionButton: FloatingActionButtonWidget(
onPressed: ()=>customWidgetKey.currentState.someMethod(someValue))
答案 2 :(得分:-1)
尝试存储小部件的状态,然后访问
class MySFWidget extends StatefulWidget {
SFWidgetState currState;
@override
SFWidgetState createState(){
currState = new SFWidgetState();
return currState;
};
}
class SFWidgetState extends State<MySFWidget> {
int prop;
void SomeMethod(){
// DO Something
}
@override
Widget build(BuildContext context) {
return null;
}
}
然后,通过以下方式访问其属性或调用方法:
myWidgetInstance.currState.prop
myWidgetInstance.currState.SomeMethod()