Home > Mobile >  Call a function from another stateful class in the build method of a class
Call a function from another stateful class in the build method of a class

Time:12-22

I have two stateful classes and I want to trigger the function triggerFunction() from one class in second class's build method with onPressed event of a button. Here are the both classes:

import 'package:flutter/material.dart';

class TriggerClass extends StatefulWidget {
  const TriggerClass({Key? key}) : super(key: key);

  @override
  State<TriggerClass> createState() => _TriggerClassState();
}

class _TriggerClassState extends State<TriggerClass> {

  void triggerFunction(){}

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(),
    );
  }
}

The Second class:

import 'package:flutter/material.dart';

class UIClass extends StatefulWidget {
  const UIClass({Key? key}) : super(key: key);

  @override
  State<UIClass> createState() => _UIClassState();
}

class _UIClassState extends State<UIClass> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () {
             // Here I want to call triggerFunction()
          },
          child: const Text('Trigger Function'),
        ),
      ),
    );
  }
}

If I use simple class without state, it does call the function but when using stateful, it doesn't.

CodePudding user response:

Try below code hope its help to you remove _ from TriggerClassState()

Make Class Public

Your Trigger Class included with Function

class TriggerClass extends StatefulWidget {
  const TriggerClass({Key? key}) : super(key: key);

  @override
  State<TriggerClass> createState() => TriggerClassState();
}

class TriggerClassState extends State<TriggerClass> {
  void triggerFunction() {
    print('Button Pressed');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(),
    );
  }
}

Your UIClass Widget call your triggerFunction

class UIClass extends StatefulWidget {
  const UIClass({Key? key}) : super(key: key);

  @override
  State<UIClass> createState() => _UIClassState();
}

class _UIClassState extends State<UIClass> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // Here I want to call triggerFunction()
            TriggerClassState().triggerFunction();
          },
          child: const Text('Trigger Function'),
        ),
      ),
    );
  }
}

Other Way Without class public or Using Constructor

Trigger Class:

class TriggerClass extends StatefulWidget {
  const TriggerClass({Key? key}) : super(key: key);

  @override
  State<TriggerClass> createState() => _TriggerClassState();
}

class _TriggerClassState extends State<TriggerClass> {
  void triggerFunction() {
    print('Button Pressed');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: UIClass(
        voidFunction: triggerFunction,
      ),
    );
  }
}

UI Class

class UIClass extends StatefulWidget {
  final Function voidFunction;
  const UIClass({required this.voidFunction, Key? key}) : super(key: key);

  @override
  State<UIClass> createState() => _UIClassState();
}

class _UIClassState extends State<UIClass> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // Here I want to call triggerFunction()
            widget.voidFunction();
          },
          child: const Text('Trigger Function'),
        ),
      ),
    );
  }
}

CodePudding user response:

It's quite simple: you should accept a function in the constructor of UIClass:

class UIClass extends StatefulWidget {
  final Function triggerFunction;
  const UIClass({required this.triggerFunction, Key? key}) : super(key: key);
...
}

And call it within you ElevatedButton:

ElevatedButton(
          onPressed: () {
            widget.triggerFunction();
          },

Here is a complete working example:

import 'package:flutter/material.dart';

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: darkBlue,
      ),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: TriggerClass(),
        ),
      ),
    );
  }
}

class TriggerClass extends StatefulWidget {
  const TriggerClass({Key? key}) : super(key: key);

  @override
  State<TriggerClass> createState() => _TriggerClassState();
}

class _TriggerClassState extends State<TriggerClass> {
  void triggerFunction() {
    print("Triggered");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: UIClass(
        triggerFunction: triggerFunction,
      ),
    );
  }
}

class UIClass extends StatefulWidget {
  final Function triggerFunction;
  const UIClass({required this.triggerFunction, Key? key}) : super(key: key);

  @override
  State<UIClass> createState() => _UIClassState();
}

class _UIClassState extends State<UIClass> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            widget.triggerFunction();
          },
          child: const Text('Trigger Function'),
        ),
      ),
    );
  }
}

CodePudding user response:

Okay, so you have a method in a triggerClass and you want to call it from the uiClass. right? for that, you have to forward the pointer of that method from triggerCLass to UiClass through Navigator.

import 'package:flutter/material.dart';

class TriggerClass extends StatefulWidget {
  const TriggerClass({Key? key}) : super(key: key);

  @override
  State<TriggerClass> createState() => _TriggerClassState();
}

class _TriggerClassState extends State<TriggerClass> {

  void triggerFunction(){}

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
......//somewhere in these widgets you have onPressed() for navigation. 
      onPressed: (){
      Navigator.push(
      context,
         MaterialPageRoute(builder: (context) => const 
       UIClass(trigger: triggerFunction)), //Here you will pass the method pointer by calling constructor
  );
}

      ),
    );
  }
}

and in UIClass receive the method from the constructor and call it wherever you want.

import 'package:flutter/material.dart';

class UIClass extends StatefulWidget {
final Function trigger;

  const UIClass({Key? key, required this.trigger}) : super(key: key);

  @override
  State<UIClass> createState() => _UIClassState();
}

class _UIClassState extends State<UIClass> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            widget.trigger();  //call it like this
          },
          child: const Text('Trigger Function'),
        ),
      ),
    );
  }
}
  • Related