skip to Main Content

I have a an app-wide file that has several functions that are used several places in the application. In one of those functions I want to call setState. This causes an issue because the function is just a function declaration and not within any statefull widget, but where it is utilized throughout the app is. Is there a way to make this work or do I need to declare the same function on multiple pages?

Function


    List<Widget> assembleHeaderWidgets(screenHeight, screenWidth, headers) {
      List<Widget> widgetRows = [];
    
      for (var header in headers) {
        widgetRows.add(
          Container(
            alignment: AlignmentDirectional.center,
            width: screenWidth * header[header.keys.first]['width'],
            height: 60,
            decoration: const BoxDecoration(
              border: Border(
                top: BorderSide(color: Colors.black, width: 2),
                left: BorderSide(color: Colors.black, width: 1),
                bottom: BorderSide(color: Colors.black, width: 2)           
              )
            ),
            child: TextField(
              controller: header[header.keys.first]['controller'],
              enabled: header[header.keys.first]['enabled'],
              textAlign: TextAlign.center,
              style: const TextStyle(
                fontWeight: FontWeight.bold,
                fontSize: 15
              ),
              decoration: InputDecoration(
                border: InputBorder.none,
                hintText: header.keys.first,
              ),
              onChanged: (text) {
                //This is where I need to setState
              },
            ),
          )
        );
      }
      return widgetRows;
    }
Widget build(BuildContext context) {
    double screenWidth = MediaQuery.of(context).size.width;
    double screenHeight = MediaQuery.of(context).size.height;
    if (customersStatic.isEmpty) {
      WidgetsBinding.instance.addPostFrameCallback((_) => setState(() {}));
    }
  
    return Scaffold(
      appBar: AppBar(
        backgroundColor: const Color.fromARGB(255, 230, 36, 36),
        centerTitle: true,
        title: const Text(
          'Customers',
          style: TextStyle(
            color: Colors.white,
            fontSize: 25
          ),
        ),
      ),
      drawer: Drawer(
        child: Column(
          children: funcs.getDrawerItems(context, screenHeight, screenWidth)
        )
      ),
      body: Column(
        children: [
          Row(
            children: funcs.assembleHeaderWidgets(
              screenHeight, 
              screenWidth,
              [
                {'Record ID': {'controller': recordIdCont, 'width': .125, 'enabled': true}},
                {'Customer Name': {'controller': nameCont, 'width': .125, 'enabled': true}},
                {'Address': {'controller': addressCont, 'width': .125, 'enabled': true}},
                {'Address2': {'controller': address2Cont, 'width': .125, 'enabled': true}},
                {'City, State': {'controller': cityStateCont, 'width': .125, 'enabled': true}},
                {'Zip': {'controller': zipCont, 'width': .125, 'enabled': true}},
                {'Zip 4': {'controller': zip4Cont, 'width': .125, 'enabled': true}},
                {'Phone': {'controller': phoneCont, 'width': .125, 'enabled': true}}
              ]
            )
          ),
...

2

Answers


  1. Chosen as BEST ANSWER

    The comment by Randal Schwartz worked perfectly

    Create a mixin on State instead to add the function to your widget but can call your local setState.


  2. You can pass VoidCallback as a parameter in the common function and call it once all the logic is completed. Like this:

    import 'package:flutter/material.dart';
    
    class Demo extends StatefulWidget {
      const Demo({super.key});
    
      @override
      State<Demo> createState() => _DemoState();
    }
    
    class _DemoState extends State<Demo> {
      void updateWidgetFunction() {
        setState(() {});
      }
    
      @override
      Widget build(BuildContext context) {
        return InkWell(
          onTap: () => commonFunction(updateWidgetFunction),
          child: Text(
            'Hello, World!',
            style: Theme.of(context).textTheme.headlineMedium,
          ),
        );
      }
    }
    
    void commonFunction(VoidCallback? callBack) {
      ///Your logic here
      callBack?.call();
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search