我有一个正在处理的 flutter 项目,我无法将整个代码放入其中,因为它的代码超过 500 行,所以我会尝试像我使用 imp 一样简单地问我的问题。部分代码。
我有一个有状态小部件,并且在扩展 State<MusicPlayer>
的类下的有状态小部件内有一些功能。
文件 lib\main.dart
只需要一个简单的函数,比如
class MyAppState extends State<MyApp>{
...
void printSample (){
print("Sample text");
}
...
这个函数在主类的有状态小部件中。
还有一个文件lib\MyApplication.dart
这个文件还有一个有状态的小部件,我可以做点什么来调用函数printSample()
吗?这里..
class MyApplicationState extends State<MyApplication>{
...
@override
Widget build(BuildContext context) {
return new FlatButton(
child: new Text("Print Sample Text"),
onPressed :(){
// i want to cal the function here how is it possible to call the
// function
// printSample() from here??
}
);
}
}
最佳答案
要调用父级的函数,可以使用回调模式。在此示例中,将一个函数 (onColorSelected
) 传递给子项。当按下按钮时, child 调用该函数:
import 'package:flutter/material.dart';
class Parent extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return ParentState();
}
}
class ParentState extends State<Parent> {
Color selectedColor = Colors.grey;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Container(
color: selectedColor,
height: 200.0,
),
ColorPicker(
onColorSelect: (Color color) {
setState(() {
selectedColor = color;
});
},
)
],
);
}
}
class ColorPicker extends StatelessWidget {
const ColorPicker({this.onColorSelect});
final ColorCallback onColorSelect;
@override
Widget build(BuildContext context) {
return Row(
children: <Widget>[
RaisedButton(
child: Text('red'),
color: Colors.red,
onPressed: () {
onColorSelect(Colors.red);
},
),
RaisedButton(
child: Text('green'),
color: Colors.green,
onPressed: () {
onColorSelect(Colors.green);
},
),
RaisedButton(
child: Text('blue'),
color: Colors.blue,
onPressed: () {
onColorSelect(Colors.blue);
},
)
],
);
}
}
typedef ColorCallback = void Function(Color color);
内部 Flutter 小部件(如按钮或表单字段)使用完全相同的模式。如果你只想调用一个不带任何参数的函数,你可以使用 VoidCallback
类型而不是定义你自己的回调类型。
如果您想通知更高的父级,您可以在每个层次结构级别上重复此模式:
class ColorPickerWrapper extends StatelessWidget {
const ColorPickerWrapper({this.onColorSelect});
final ColorCallback onColorSelect;
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(20.0),
child: ColorPicker(onColorSelect: onColorSelect),
)
}
}
在 Flutter 中不鼓励从父 widget 调用子 widget 的方法。相反,Flutter 鼓励您将 child 的状态作为构造函数参数传递。您只需在父窗口小部件中调用 setState
来更新其子窗口,而不是调用子窗口的方法。
另一种方法是 Flutter 中的 controller
类(ScrollController
、AnimationController
、...)。这些也作为构造函数参数传递给子级,它们包含控制子级状态的方法,而无需在父级上调用 setState
。示例:
scrollController.animateTo(200.0, duration: Duration(seconds: 1), curve: Curves.easeInOut);
然后要求 children 收听这些变化以更新他们的内部状态。当然,你也可以实现自己的 Controller 类。如果需要,我建议您查看 Flutter 的源代码以了解其工作原理。
Futures 和 Streams 是传递状态的另一种选择,也可以用于调用子函数。
但我真的不推荐它。如果你需要调用一个子部件的方法,那很像你的应用架构有缺陷。 尝试将状态提升到共同祖先!
https://stackoverflow.com/questions/51029655/