Flutter: calling child class function from parent class of onother file

640

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.

  1. define a ChangeNotifier (PressedProvider) which will save current state of the app in a unique location and the behavior of your onPress function
  2. you wrap your app with a ChangeNotifierProvider widget
  3. you wrap the receiving Widget with a Consumer
  4. you get the Provider.of() when you need to do something and call a method on it
  5. 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()),
    );
  }
}
Share:
640
Alexey Lo
Author by

Alexey Lo

Updated on December 24, 2022

Comments

  • Alexey Lo
    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
      lenz over 3 years
      Is there a particular reason you are using a stateful widget in button.dart ?
    • Raine Dale Holgado
      Raine Dale Holgado over 3 years
      what if when you pressed that MyButton, try sending a flag(trigger) like true or false. so if true on your initstate run your methodA.