从另一个有状态小部件调用一个有状态小部件中的方法-Flutter
我有一个颤振项目,我正在工作,我不能把整个代码,因为它超过500行的代码,所以我会尽量问我的问题,因为我使用的imp.部分的代码简单 我有一个有状态的小部件,在扩展从另一个有状态小部件调用一个有状态小部件中的方法-Flutter,flutter,dart,Flutter,Dart,我有一个颤振项目,我正在工作,我不能把整个代码,因为它超过500行的代码,所以我会尽量问我的问题,因为我使用的imp.部分的代码简单 我有一个有状态的小部件,在扩展State 文件lib\main.dart 只需要一个简单的函数,比如 class MyAppState extends State<MyApp>{ ... void printSample (){ print("Sample text"); } ... 要调用父函数,可以使用回调模式。在本例中,函数(onColor
State
文件lib\main.dart
只需要一个简单的函数,比如
class MyAppState extends State<MyApp>{
...
void printSample (){
print("Sample text");
}
...
要调用父函数,可以使用回调模式。在本例中,函数(
onColorSelected
)被传递给子级。按下按钮时,孩子调用该函数:
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);
在flatter中,不鼓励从父窗口小部件调用子窗口小部件的方法。相反,flatter鼓励您将子对象的状态作为构造函数参数传递。您只需在父窗口小部件中调用
setState
,而不是调用子窗口的方法来更新其子窗口
另一种方法是颤振中的
控制器
类(滚动控制器
,动画控制器
,…)。这些参数也作为构造函数参数传递给子级,它们包含控制子级状态的方法,而无需在父级上调用setState
。例如:
scrollController.animateTo(200.0, duration: Duration(seconds: 1), curve: Curves.easeInOut);
然后,要求子级侦听这些更改以更新其内部状态。当然,您也可以实现自己的控制器类。如果需要,我建议您查看flatter的源代码,了解它是如何工作的
未来和流是传递状态的另一种替代方法,也可用于调用子函数
但我真的不推荐。如果您需要调用子小部件的方法,则很可能您的应用程序架构有缺陷尝试将状态向上移动到共同祖先我通过反复试验找到了另一种解决方案,但它奏效了
import 'main.dart' as main;
然后将这一行添加到onPressed下
main.MyAppState().printSample();
如果要调用printSample()func,可以使用:
class Myapp extends StatefulWidget{
...
MyappState myAppState=new MyappState();
@override
MyappState createState() => myAppState;
void printSample(){
myAppState.printSample();
}
}
class MyAppState extends State<MyApp>{
void printSample (){
print("Sample text");
}
}
...............
Myapp _myapp = new Myapp();
myapp.printSample();
...
类Myapp扩展StatefulWidget{
...
MyappState MyappState=新的MyappState();
@凌驾
MyappState createState()=>MyappState;
void printSample(){
myAppState.printSample();
}
}
类MyAppState扩展了状态{
无效打印样本(){
打印(“样本文本”);
}
}
...............
Myapp _Myapp=新的Myapp();
myapp.printSample();
...
您可以尝试一下,它将从Page1
(StatefulWidget
)小部件调用Page2
(StatefulWidget
)中定义的方法
class Page1扩展了StatefulWidget{
@凌驾
_Page1State createState();
}
类_Page1State扩展状态{
@凌驾
小部件构建(构建上下文){
返回脚手架(
正文:中(
孩子:升起按钮(
子项:文本(“调用第2页方法”),
onPressed:()=>Page2().method(),
),
),
);
}
}
类Page2扩展了StatefulWidget{
方法()=>createState().methodInPage2();
@凌驾
_Page2State createState();
}
类_Page2State扩展状态{
methodInPage2()=>打印(“第2页中的方法”);
@凌驾
小部件构建(BuildContext上下文)=>Container();
}
您可以通过使用widget的键来实现
myWidget.dart
class MyWidget extends StatefulWidget {
const MyWidget ({Key key}) : super(key: key);
@override
State<StatefulWidget> createState()=> MyState();
}
class MyState extends State<MyWidget >{
Widget build(BuildContext context){ return ....}
void printSample (){
print("Sample text");
}
}
通过该键,您可以调用状态内的任何公共方法
_myKey.currentState.printSample();
这里主页是父页面,子页面是子页面。有一个名为onSelectItem的方法,我们需要从子页面调用它
class HomePage extends StatefulWidget {
@override HomePageState createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
onSelectItem(String param) {
print(param);
}
@override Widget build(BuildContext context) {
}
}
class ChildPage extends StatefulWidget {
final HomePageState homePageState;
ChildPage({Key key, @required this.homePageState}) : super(key: key);
_ChildPageState createState() => _ChildPageState();
}
class _ChildPageState extends State<ChildPage> {
@override Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
widget.homePageState.onSelectItem("test");
},
child: const Text(
'Click here',
style: TextStyle(fontSize: 20)
),
);
}
}
类主页扩展StatefulWidget{
@覆盖HomePageState createState()=>HomePageState();
}
类HomePageState扩展了状态{
onSelectItem(字符串参数){
打印(参数);
}
@覆盖小部件构建(构建上下文){
}
}
类ChildPage扩展StatefulWidget{
最终主页状态主页状态;
ChildPage({Key Key,@required this.homePageState}):超级(Key:Key);
_ChildPageState createState()=>\u ChildPageState();
}
类_ChildPageState扩展状态{
@覆盖小部件构建(构建上下文){
返回上升按钮(
已按下:(){
widget.homePageState.onSelectItem(“测试”);
},
子:常量文本(
“单击此处”,
样式:文本样式(字体大小:20)
),
);
}
}
因此,通过使用小部件和父类状态我们可以调用父类方法。 显然,您只需创建一个只包含一个方法的文件,就可以直接调用它 例如,我想在名为
custom\u show\u bottom\u sheet.dart的文件中创建一个showModalBottomSheet方法:
import 'package:flutter/material.dart';
customShowBottomSheet(context, Widget child){
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return Wrap(
children: <Widget>[
child,
],
);
});
}
希望这是一个帮助!如果我误解了你的问题或其他什么,请告诉我。在使用回调时,对于简单的用例来说,'s很好,对于更复杂的设置,它们可能应该被视为反模式,因为它们与小部件类型挂钩,并且依赖于低级实现逻辑
如果您发现自己添加了越来越多的回调/globalkey,并且开始变得混乱,那么可能是时候切换到+。通过这种方式,您可以将事件与特定的小部件类型分离,并抽象出小部件间的通信逻辑
注册一个事件控制器
在顶级小部件(应用程序级或页面级,取决于您的需要)中创建StreamController
实例,并确保在dispose()
方法中释放它:
class\u TopLevelPageState扩展状态{
StreamController eventController=StreamController.broadcast();
// ...
@凌驾
无效处置(){
eventController.close();
super.dispose();
}
}
将eventController
实例作为构造函数参数向下传递到
GlobalKey<MyState> _myKey = GlobalKey();
MyWidget(
key : _myKey,
)
_myKey.currentState.printSample();
class HomePage extends StatefulWidget {
@override HomePageState createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
onSelectItem(String param) {
print(param);
}
@override Widget build(BuildContext context) {
}
}
class ChildPage extends StatefulWidget {
final HomePageState homePageState;
ChildPage({Key key, @required this.homePageState}) : super(key: key);
_ChildPageState createState() => _ChildPageState();
}
class _ChildPageState extends State<ChildPage> {
@override Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
widget.homePageState.onSelectItem("test");
},
child: const Text(
'Click here',
style: TextStyle(fontSize: 20)
),
);
}
}
import 'package:flutter/material.dart';
customShowBottomSheet(context, Widget child){
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return Wrap(
children: <Widget>[
child,
],
);
});
}
import 'package:flutter/material.dart';
import '../custom_show_bottom_sheet.dart';
class TestScreen extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: FloatingActionButton(
onPressed: (){
customShowBottomSheet( //A method is called here
context,
Container(
height: 200,
child: Text("This is a test"),
)
);
}),
),
);
}
}