I have a custom button widget:
class Button extends StatelessWidget { final String text; Button(this.text); @override Widget build(BuildContext context) { return Container( height: 50, child: SizedBox( width: double.infinity, child: RaisedButton( onPressed: () => {}, // Use the function from parent Widget child: Padding( padding: EdgeInsets.symmetric(vertical: 13), child: Text( text, style: TextStyle(fontWeight: FontWeight.bold), )), color: COLOR_BLUE, textColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)), ), ), ); } }
Then in parent Widget I want to pass a onPressed
method to this button widget:
... myMethod () => { // do some stuff } ... Padding( padding: EdgeInsets.only(bottom: 10), child: Button("Log in", myMethod), ), ...
How can I tell a button widget to use the myMethod
for onPress
?
Steps to Pass Data to Stateful Widget in Flutter To pass data to stateful widget, first of all, create two pages. Now from the first page open the second page and pass the data. Inside the second page, access the variable using the widget. For example widget.
Calling a method of child widget from a parent widget is discouraged in Flutter. Instead, Flutter encourages you to pass down the state of a child as constructor parameters. Hence instead of calling a method of the child, you just call setState in the parent widget to update its children.
Functions are first-class objects in Dart and can be passed as parameters to other functions. We pass a function to a widget essentially saying, invoke this function when something happens. Callbacks using interfaces like Android have too much boilerplate code for a simple callback.
Use the VoidCallback type, like this. Check the line comments on the code as well for more information:
class Button extends StatelessWidget { final String text; final VoidCallback callback; // Notice the variable type Button(this.text, this.callback); @override Widget build(BuildContext context) { return Container( height: 50, child: SizedBox( width: double.infinity, child: RaisedButton( onPressed: callback, // Simply put the function name here, DON'T use () child: Padding( padding: EdgeInsets.symmetric(vertical: 13), child: Text( text, style: TextStyle(fontWeight: FontWeight.bold), )), color: COLOR_BLUE, textColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(25)), ), ), ); } }
There are a few predefined types that already exist.
If you want to create a parameter something like this:
onPressed: () { },
Then you can define it in your class like so:
class MyWidget extends StatelessWidget { MyWidget({Key key, this.onPressed}) : super(key: key); final VoidCallback onPressed; // ... }
The typedef
is defined in the source code like this:
typedef VoidCallback = void Function();
The asynchronous version is AsyncCallback
.
typedef AsyncCallback = Future<void> Function();
If you want to create a parameter something like this:
onPressed: (value) { },
Then you can define it in your class like so:
class MyWidget extends StatelessWidget { MyWidget({Key key, this.onPressed}) : super(key: key); final ValueSetter<String> onPressed; // ... }
The typedef is defined in the source code like this:
typedef ValueSetter<T> = void Function(T value);
If you want to specify that the function only gets called when there is a change then use ValueChanged instead.
typedef ValueChanged<T> = void Function(T value);
The asynchronous version is AsyncValueSetter
.
typedef AsyncValueSetter<T> = Future<void> Function(T value);
If you want to create a parameter something like this:
onPressed: () => value,
Then you can define it in your class like so:
class MyWidget extends StatelessWidget { MyWidget({Key key, this.onPressed}) : super(key: key); final ValueGetter<String> onPressed; // ... }
The typedef is defined in the source code like this:
typedef ValueGetter<T> = T Function();
The asynchronous version is AsyncValueGetter
.
typedef AsyncValueGetter<T> = Future<T> Function();
As you can see from all of the examples above, everything is just a typedef
for a Function
. So it is easy enough to make your own.
Say you want to do something like this:
onEvent: (context, child) => value,
Then you would make the typedef like this:
typedef MyEventCallback = int Function(BuildContext context, Widget widget);
And use it like this:
class MyWidget extends StatelessWidget { MyWidget({Key key, this.onEvent}) : super(key: key); final MyEventCallback onEvent; // ... }
See the documentation for more.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With