[英]How to call function from Stateful widget
I have seen many questions similar to mine in Stack Overflow but it did not fit my case since they were asking to call function
from - to Stateful
widget.我在 Stack Overflow 中看到过很多与我类似的问题,但它不适合我的情况,因为他们要求从 - 到
Stateful
小部件调用function
。
I want call function located into State Full
widget from a non Stateful-Stateless Widget
我想调用 function 位于
State Full
来自非Stateful-Stateless Widget
My code is complicated, I will try to explain it below:我的代码很复杂,我将在下面尝试解释:
class Example extends StatefulWidget {
const Example({Key? key}) : super(key: key);
@override
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
void myFunction(){
print('hello dart');
}
ShowDialog showDialog = ShowDialog();
@override
Widget build(BuildContext context) {
return TextButton(
onPressed: (){
showDialog.myDialog();
},
child: Text('tab me')
);
}
}
class ShowDialog {
Widget myDialog(){
return showDialog(
builder: (BuildContext context) {
return SimpleDialog(
backgroundColor: Colors.deepPurple[900],
titleTextStyle: const TextStyle(
color: Colors.red, fontSize: 18),
children: [
ElevatedButton(
onPressed: () {
// here i need to call myFunction() Methood
},
child: const Text("tab")
),
],
)
},
);
}
}
How can I go through this?我怎么能通过这个go?
you can call it directly like this:你可以像这样直接调用它:
_ExampleState().myFunction();
The full code:完整代码:
class Example extends StatefulWidget {
const Example ({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<Example > createState() => _ExampleState ();
}
class _ExampleState extends State<Example > {
void myFunction(){
print('hello dart');
}
ShowDialog showDialog = ShowDialog();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: TextButton(
onPressed: (){
showDialog.myDialog(context);
},
child: Text('tab me')
)
);
}
}
class ShowDialog {
Future myDialog(BuildContext context){
return showDialog(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
backgroundColor: Colors.deepPurple[900],
titleTextStyle: const TextStyle(
color: Colors.red, fontSize: 18),
children: [
ElevatedButton(
onPressed: () {
// here i need to call myFunction() Methood
_ExampleState().myFunction();
},
child: const Text("tab")
),
],
);
},
);
}
}
The result:结果:
So in order to have your showDialog
function call MyFunction
, you need to pass it as if it was a callback.因此,为了让您的
showDialog
function 调用MyFunction
,您需要将其作为回调传递。
To do that, first add a Function
callback in your class:为此,首先在您的 class 中添加一个
Function
回调:
class ShowDialog {
ShowDialog({required this.callback});
VoidCallback callback;
...
}
Then you have to pass the callback when you create the object:然后你必须在创建object时传递回调:
ShowDialog showDialog = ShowDialog(callback: myFunction);
You actually can't do that tho, because this is a class variable, a simple solution is to turn your showDialog
variable into a getter, this means showDialog
will compute again every time you call it, which is not ideal but I don't think it will be terrible for this specific use-case.你实际上不能那样做,因为这是一个 class 变量,一个简单的解决方案是将你的
showDialog
变量变成一个 getter,这意味着每次你调用它时showDialog
都会再次计算,这并不理想,但我不认为对于这个特定的用例来说会很糟糕。
ShowDialog get showDialog => ShowDialog(callback: myFunction);
note the get keyword and the =>
instead of an equal sign注意 get 关键字和
=>
而不是等号
You can also pass the callback as part of the myDialog
method, this is probably actually a better idea:您还可以将回调作为
myDialog
方法的一部分传递,这实际上可能是一个更好的主意:
Widget myDialog(VoidCallback callback) {
return showDialog(
builder: (BuildContext context) {
return SimpleDialog(
backgroundColor: Colors.deepPurple[900],
titleTextStyle: const TextStyle(
color: Colors.red, fontSize: 18),
children: [
ElevatedButton(
onPressed: callback,
child: const Text("tab")
),
],
)
},
);
}
I wrote this function that returns a Dialog in a separate file:我写了这个 function,它在一个单独的文件中返回一个对话框:
Future myDialog({required BuildContext dialogContext, required Function function}){
return showDialog(
context: dialogContext,
builder: (BuildContext context) {
return SimpleDialog(
backgroundColor: Colors.deepPurple[900],
titleTextStyle: const TextStyle(
color: Colors.red, fontSize: 18),
children: [
ElevatedButton(
onPressed: () {
function();
},
child: const Text("tab")
),
],
);
},
);
}
then I made 2 functions, the first one just print (Hello first function) and the second function print (Hello Second function) and set the state and rebuild the widget tree然后我做了 2 个函数,第一个只是打印(你好第一个函数)和第二个 function 打印(你好第二个函数)并设置 state 并重建小部件树
I made 2 TextButton: the first TextButton call the myDialog function and pass the firstFunction as a parameter, the second TextButton call the myDialog function and pass the secondFunction as a parameter:我制作了 2 个 TextButton:第一个 TextButton 调用 myDialog function 并将 firstFunction 作为参数传递,第二个 TextButton 调用 myDialog function 并将 secondFunction 作为参数传递:
the code:代码:
class ExampleState extends State<Example > {
void firstFunction(){
print('Hello first function');
}
void secondFunction(){
setState(() {
print('Hello Second function');
});
}
@override
Widget build(BuildContext context) {
print('build');
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children: [
TextButton(
onPressed: (){
myDialog(dialogContext: context, function: firstFunction );
},
child: Text('First Dialog')
),
TextButton(
onPressed: (){
myDialog(dialogContext: context, function: secondFunction );
},
child: Text('Second Dialog')
)
],
),
)
);
}
}
notice that I added a print('build');注意我添加了一个 print('build'); so I can know when it rebuild the widget tree
这样我就可以知道它什么时候重建小部件树
The result:结果:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.