触发从小部件到状态对象的函数 [英] Trigger a function from a widget to a State object
问题描述
这是场景的简化版本:
class ParentWdiegt extends StatelessWidget{
//
//
floatinActionButton: FloatingActionButtonWidget(onPressed:()=>CustomWidgetState.someMethod(someValue))
//
//somewhere in the ParentWidget tree
child: CustomWidget() //is stateful
}
自定义控件状态
class CustomWidgetState extends State<CustomWidget>{
//trigger this function when FAB is pressed in parent widget
someMethod(SomeValue) {//}
}
有什么方法可以在不使用 InheritedWidget
的情况下,在按下 FAB 时在要触发的状态对象中公开 someMethod
吗?
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.
如果你想调用方法,这使用相同的原则:在小部件之间共享的 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.
这是一个使用 Stream
的例子.
Here's an example using 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();
}
}
在这个例子中,每当点击 _ParentWidgetState
实例化的 RaisedButton
时,都会调用 AnotherWidget
的 someMethod
被执行.
In this example, someMethod
of AnotherWidget
will be called whenever a click on the RaisedButton
instantiated by _ParentWidgetState
is performed.
这篇关于触发从小部件到状态对象的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!