触发功能从小部件到状态对象 [英] Trigger a function from a widget to a State object
问题描述
这是该方案的简化版本:
This is a simplified version of the scenario:
class ParentWdiegt extends StatelessWidget{
//
//
floatinActionButton: FloatingActionButtonWidget(onPressed:()=>CustomWidgetState.someMethod(someValue))
//
//somewhere in the ParentWidget tree
child: CustomWidget() //is stateful
}
CustomWidgetState
CustomWidgetState
class CustomWidgetState extends State<CustomWidget>{
//trigger this function when FAB is pressed in parent widget
someMethod(SomeValue) {//}
}
有什么方法可以公开 someMethod
按下FAB而不使用 InheritedWidget
?
Is there any way that I can expose someMethod
in the state object to be triggered when FAB is pressed without using InheritedWidget
?
推荐答案
GlobalKey
允许轻松访问任何小部件的状态;躲开它。
窗口小部件不应与其他窗口小部件直接互动。这是Flutter的核心原则之一。
While GlobalKey
allows for an easy access to any widget's state ; avoid it.
Widgets should not interact with other widgets directly. This is one of the core principle of Flutter.
Flutter使用了反应式编程。小部件之间通过提交事件进行通信。不是直接编辑所需的小部件。
Flutter uses reactive programming instead. Where widgets communicate with each others by submitting events. Not by directly editing the desired widget.
明显的好处是小部件保持独立。并且可能有数十个小部件可以使用相同的原理相互通信。
The obvious benefit is that widgets stays independant. And potentially dozens of widgets can communicate with each others using the same principle.
我已经举了一个例子此处说明如何使两个不同的小部件共享共同的可编辑值。
I already made an example here on how to make two different widgets share a common editable value.
如果要调用方法,则使用相同的原理:A Listenable
或 Stream
之间共享小部件。但不使用 AnimatedWidget
或 StreamBuilder
进行监听。
相反,我们将手动进行侦听(这需要更多样板)以触发自定义功能。
If you want to call methods instead, this uses the same principle : A Listenable
or Stream
shared between widgets. But without using AnimatedWidget
or StreamBuilder
for the listening.
Instead we'll do the listening manually (which requires slighly more boilerplate) to trigger a custom function.
以下是使用的示例流
。
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每当单击由<$ c $实例化的
c> _ParentWidgetState 被执行。 RaisedButton
时,将调用另一个控件
的
In this example, someMethod
of AnotherWidget
will be called whenever a click on the RaisedButton
instantiated by _ParentWidgetState
is performed.
这篇关于触发功能从小部件到状态对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!