skip to Main Content

I am new to flutter) I want to make function which calls showDialog() with 2 TextField() when user press the FloatingActionButton() in the main.dart file.

I don’t know how to call a function in a main file Stateful Widget from another StatefulWidget (from another file called VVid.dart)

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  State<MyHomePage> createState() => MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  String cardText = '';

  void updateCardText(String text) {
    setState(() {
      cardText = text;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Transaction App'),
        ),
        body: Container(
          color: Colors.amber,
          height: 200,
          width: 300,
          child: Card(
            child: Text(cardText),
          ),
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              // Forma.showTextField(context);
            });
          },
          child: Icon(Icons.add),
        ));
  }
}

// vvid.dart //////////////////////////////////////

class Forma extends StatefulWidget {
  @override
  State<Forma> createState() => FormaState();
}

class FormaState extends State<Forma> {
  final vvidText = TextEditingController();

  final vvidAmount = TextEditingController();

  void showTextField(BuildContext context) {
    showDialog(
      context: context,
      builder: ((context) {
        return AlertDialog(
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(
                controller: vvidText,
                decoration: const InputDecoration(
                    hintText: "Title",
                    hintStyle: TextStyle(color: Colors.grey)),
              ),
              TextField(
                controller: vvidAmount,
                decoration: const InputDecoration(
                    hintText: "Amount",
                    hintStyle: TextStyle(color: Colors.grey)),
                keyboardType: TextInputType.number,
              ),
            ],
          ),
          title: Text('My Transaction'),
          actions: [
            Row(
              children: [
                TextButton(
                    onPressed: (() {
                      Navigator.of(context).pop();
                    }),
                    child: Text('Ok')),
                TextButton(
                    onPressed: (() {
                      Navigator.pop(context, vvidText.text);
                    }),
                    child: Text('Close')),
              ],
            ),
          ],
        );
      }),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

2

Answers


  1. You could rewrite your Forma class like this:

    class Forma extends StatefulWidget {
      @override
      State<Forma> createState() => FormaState();
    
      static Future<String?> showTextField(BuildContext context) async {
        return await showDialog(
          context: context,
          builder: ((context) {
            return Forma();
          }),
        );
      }
    }
    
    class FormaState extends State<Forma> {
      final vvidText = TextEditingController();
    
      final vvidAmount = TextEditingController();
    
      @override
      Widget build(BuildContext context) {
        return AlertDialog(
          content: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(
                controller: vvidText,
                decoration: const InputDecoration(
                    hintText: "Title",
                    hintStyle: TextStyle(color: Colors.grey)),
              ),
              TextField(
                controller: vvidAmount,
                decoration: const InputDecoration(
                    hintText: "Amount",
                    hintStyle: TextStyle(color: Colors.grey)),
                keyboardType: TextInputType.number,
              ),
            ],
          ),
          title: Text('My Transaction'),
          actions: [
            Row(
              children: [
                TextButton(
                    onPressed: (() {
                      Navigator.of(context).pop();
                    }),
                    child: Text('Ok')),
                TextButton(
                    onPressed: (() {
                      Navigator.pop(context, vvidText.text);
                    }),
                    child: Text('Close')),
              ],
            ),
          ],
        );
      }
    }
    

    And let this be the onPressed:

              onPressed: () {
                Forma.showTextField(context).then((value) => setState(() {
                      cardText = value ?? '';
                    }));
              },
    

    You will see the vvidText will be passed if you press the close button

    Login or Signup to reply.
  2. you don’t need your Forma class, just extract the dialog method into your main class, and make it return the values from your controllers, then use that value to update your card:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.green,
          ),
          home: MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      State<MyHomePage> createState() => MyHomePageState();
    }
    
    class MyHomePageState extends State<MyHomePage> {
      String cardText = '';
    
      void updateCardText(String text) {
        setState(() {
          cardText = text;
        });
      }
    
      Future<String?> showTextField(BuildContext context) {
        final vvidText = TextEditingController();
        final vvidAmount = TextEditingController();
    
        return showDialog<String?>(
          context: context,
          builder: ((context) {
            return AlertDialog(
              content: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  TextField(
                    controller: vvidText,
                    decoration: const InputDecoration(hintText: "Title", hintStyle: TextStyle(color: Colors.grey)),
                  ),
                  TextField(
                    controller: vvidAmount,
                    decoration: const InputDecoration(hintText: "Amount", hintStyle: TextStyle(color: Colors.grey)),
                    keyboardType: TextInputType.number,
                  ),
                ],
              ),
              title: const Text('My Transaction'),
              actions: [
                Row(
                  children: [
                    TextButton(
                        onPressed: (() {
                          Navigator.of(context).pop();
                        }),
                        child: const Text('Ok')),
                    TextButton(
                        onPressed: (() {
                          Navigator.pop(context, vvidText.text);
                        }),
                        child: const Text('Close')),
                  ],
                ),
              ],
            );
          }),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              title: const Text('Transaction App'),
            ),
            body: Container(
              color: Colors.amber,
              height: 200,
              width: 300,
              child: Card(
                child: Text(cardText),
              ),
            ),
            floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
            floatingActionButton: FloatingActionButton(
              onPressed: () {
                showTextField(context).then((value) {
                  if (value != null) {
                    updateCardText(value);
                  }
                });
              },
              child: const Icon(Icons.add),
            ));
      }
    }
    

    you can even return from your showDialog method a List<String>? if you want to return the value from both textFields

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search