Flutter: calling child class function from parent class of onother file
Solution 1
first, you will have to import the file as a package
in main.dart
:
Main.dart: (just writing the way to import the file)
import 'package:prioject_name/file_name.dart';
Note: this is for files under lib
directory.
if your file is under a different directory inside lib
then add the path accordingly,
eg: Button.dart is inside the widgets folder inside the lib folder:
lib
|____widgets
|____Button.dart
then the import statement will be as follows:
import 'package:prioject_name/widgets/Button.dart';
Then try your global key method to call the function:
If it is still not working then you can use my method,
how I call methods from different class
in onPressed
or onTapped
:
your Button.dart file.
import 'package:flutter/material.dart';
// changed the method definition class
class MyButton extends StatefulWidget {
void methodA(){
print('methodA');
}
@override
_MyButtonState createState() => _MyButtonState();
}
class _MyButtonState extends State<MyButton> {
@override
Widget build(BuildContext context) {
...
widget.methodA(); // this would call the method A, anywhere inside the Widget build() function.
return Container( );
}
}
Now in Main.dart:
import 'package:prioject_name/Button.dart';
//call the function here using className().functioName();
....
onPressed(){
MyButton().methodA();
}
Solution 2
Take a look at the InheritedWidget class (and watch the videos).
Base class for widgets that efficiently propagate information down the tree.
You can look at creating an InheritedWidget
that contains a ValueNotifier
.
class MyInheritedWidget extends InheritedWidget {
final ValueNotifier<int> buttonTapCountNotifier;
const MyInheritedWidget({
Key key,
@required this.buttonTapCountNotifier,
@required Widget child,
}) : assert(child != null),
super(key: key, child: child);
static MyInheritedWidget of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
}
}
Your MyButton
class can call MyInheritedWidget.of(context).buttonTapCountNotifier
to get hold of the ValueNotifier
and add a listener to it.
Each time the ValueNotifier
notifies your MyButton
class that the value has been incremented, you can execute methodA
.
Solution 3
You could use the Provider package which is quite the preferred method to manage state in Flutter apps. This will help you as well in organizing and growing the app in a clever way.
Take a look at the working code below.
- define a ChangeNotifier (PressedProvider) which will save current state of the app in a unique location and the behavior of your onPress function
- you wrap your app with a ChangeNotifierProvider widget
- you wrap the receiving Widget with a Consumer
- you get the Provider.of() when you need to do something and call a method on it
- it will notify the Consumer of a change
Code:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(ChangeNotifierProvider<PressedProvider>( // 2
create: (_) => PressedProvider(),
child: MyApp(),
));
}
class PressedProvider extends ChangeNotifier { // 1
void pressButton() {
print("pressButton");
notifyListeners();
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
leading: Consumer<PressedProvider>( // 3
builder: (_, provider, widget) => IconButton(
icon: Icon(Icons.help),
onPressed: () {
provider.pressButton();
},
),
),
),
body: Center(
child: MyButton(),
),
),
);
}
}
class MyButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
PressedProvider provider = Provider.of<PressedProvider>(context); // 4
return Center(
child: RawMaterialButton(
child: Text("Press me"),
onPressed: () => provider.pressButton()),
);
}
}
Alexey Lo
Updated on December 24, 2022Comments
-
Alexey Lo over 1 year
Question: How to call methodA() from onPressed() of IconButton. I've tryed to do this by using GlobalKey: GlobalKey<_MyButtonState> globalKey = GlobalKey(); But it's returns an error.
I have read many forums on this and I have tried all the solutions posed but none of them are working for me.
CODE:
main.dart
import 'package:flutter/material.dart'; import 'button.dart'; void main() { runApp(MaterialApp( title: 'My app', home: MyApp(),)); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( leading: IconButton( icon: Icon(Icons.help), onPressed: () { // how can I call methodA from here? }, ), ), body: HomePage(), ), ); } } class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return Center( child: MyButton(), ); } }
button.dart
import 'package:flutter/material.dart'; class MyButton extends StatefulWidget { @override _MyButtonState createState() => _MyButtonState(); } class _MyButtonState extends State<MyButton> { @override Widget build(BuildContext context) { return Container( ); } void methodA(){ print('methodA'); } }
I have read many forums on this and I have tried all the solutions posed but none of them are working for me.
-
lenz over 3 yearsIs there a particular reason you are using a stateful widget in button.dart ?
-
Raine Dale Holgado over 3 yearswhat if when you pressed that MyButton, try sending a flag(trigger) like true or false. so if true on your initstate run your methodA.
-