dart 如何从另一个文件中的另一个StatefulWidget调用主文件StatefulWidget中的函数?

yuvru6vn  于 2023-03-21  发布在  其他
关注(0)|答案(2)|浏览(121)

我是flutter的新手)我想创建一个函数,当用户按下主.dart文件中的FloatingActionButton()时,该函数调用带有2个TextField()的showDialog()。
我不知道如何从另一个StatefulWidget(从另一个名为VVid.dart的文件)调用主文件StatefulWidget中的函数

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();
  }
}
dgiusagp

dgiusagp1#

你可以像这样重写你的Forma类:

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')),
          ],
        ),
      ],
    );
  }
}

假设这是onPressed

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

您将看到,如果按下关闭按钮,vvidText将被传递

rbl8hiat

rbl8hiat2#

你不需要Forma类,只需要把dialog方法提取到你的主类中,让它从你的控制器返回值,然后用那个值更新你的卡片:

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),
        ));
  }
}

如果你想从两个textFields返回值,你甚至可以从showDialog方法返回List<String>?

相关问题