Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

call method in one stateful widget from another stateful widget - Flutter

Tags:

flutter

dart

I have a flutter project that I am working on I can't put the whole code cause its more than 500 lines of code so I will try to ask my question as simply as I acn using the imp. section of the code .

I am having a stateful widget and having some functions inside that stateful widget under the class that extends State<MusicPlayer>

file lib\main.dart

just take a simple function like

class MyAppState extends State<MyApp>{ ... void printSample (){   print("Sample text"); } ... 

this function is inside the stateful widget inside main class .

there is another file lib\MyApplication.dart

this file also has a stateful widget can I do something so that I can call the function printSample() here ..

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??         }     );   } } 
like image 613
Aman Malhotra Avatar asked Jun 25 '18 18:06

Aman Malhotra


People also ask

How do you call a widget from another widget in Flutter?

How to Call Method in One Stateful Widget From Another Stateful Widget In Flutter? To call a function of a parent, you can use the callback pattern. In this example, a function on the color selected is passed to the child.

How do you pass data from one stateful widget to another in Flutter?

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.

How do you call a method from another class in Flutter Dart?

We can access it easily just like below. Show activity on this post. Show activity on this post. Import HomePage class in DetailsPage and make a new instance out of it, then call the method you want if it's a public one.


2 Answers

To call a function of a parent, you can use the callback pattern. In this example, a function (onColorSelected) is passed to the child. The child calls the function when a button is pressed:

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); 

Internal Flutter widgets like buttons or form fields use exactly the same pattern. If you only want to call a function without any arguments, you can use the VoidCallback type instead defining your own callback type.


If you want to notify a higher up parent, you can just repeat this pattern on every hierarchy level:

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),     )   } } 

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. Instead of calling a method of the child, you just call setState in the parent widget to update its children.


One alternative approach are the controller classes in Flutter (ScrollController, AnimationController, ...). These are also passed to the children as constructor parameters, and they contain methods to control the state of the child without calling setState on the parent. Example:

scrollController.animateTo(200.0, duration: Duration(seconds: 1), curve: Curves.easeInOut); 

The children are then required to listen to these changes to update their internal state. Of course, you can also implement your own controller class. If you need to, I recommend you to look at the source code of Flutter to understand how that works.


Futures and streams are another alternative to pass down state, and could also be used to call a function of a child.

But I really don't recommend it. If you need to call a method of a child widget, it is very like that your application architecture is flawed. Try to move the state up to the common ancestor!

like image 98
boformer Avatar answered Sep 19 '22 10:09

boformer


You can do that by use key of 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");       }           } 

now when use MyWidget declare GlobalKey as global key

  GlobalKey<MyState> _myKey = GlobalKey(); 

and pass it when create widget

MyWidget( key : _myKey, ) 

by this key you can call any public method inside state

_myKey.currentState.printSample(); 
like image 25
Mahmoud Abu Alheja Avatar answered Sep 19 '22 10:09

Mahmoud Abu Alheja