我正在构建一个Flutter应用程序,我需要将功能传递给其他小部件。

我有这8个TextFormFields及其值。
当我按下灰色按钮“Smazat hodnotypasažérů”时,它应该清除所有文本字段。
我在一个文件pasazeri.dart中有文本字段,在另一个文件deleteBtn.dart中有按钮。
我想我可以将清除框的功能发送给我的按钮小部件,但它不起作用。
这是我的pasazeri.dart的完整代码

import 'package:flutter/services.dart';
import 'deleteBtn.dart';

class Pasazeri extends StatefulWidget {
  @override
  _PasazeriState createState() => _PasazeriState();
}

class _PasazeriState extends State<Pasazeri> {
  final FocusNode pasazer1 = FocusNode();
  final FocusNode pasazer2 = FocusNode();
  final FocusNode pasazer3 = FocusNode();
  final FocusNode pasazer4 = FocusNode();
  final FocusNode pasazer5 = FocusNode();
  final FocusNode pasazer6 = FocusNode();
  final FocusNode pasazer7 = FocusNode();
  final FocusNode pasazer8 = FocusNode();

  TextEditingController contPasazer1 = TextEditingController();
  TextEditingController contPasazer2 = TextEditingController();
  TextEditingController contPasazer3 = TextEditingController();
  TextEditingController contPasazer4 = TextEditingController();
  TextEditingController contPasazer5 = TextEditingController();
  TextEditingController contPasazer6 = TextEditingController();
  TextEditingController contPasazer7 = TextEditingController();
  TextEditingController contPasazer8 = TextEditingController();

  _fieldFocusChange(
      BuildContext context, FocusNode currentFocus, FocusNode nextFocus) {
    currentFocus.unfocus();
    FocusScope.of(context).requestFocus(nextFocus);
  }

  void clearBoxes() {
    setState(() {
      contPasazer1.clear();
      contPasazer2.clear();
      contPasazer3.clear();
      contPasazer4.clear();
      contPasazer5.clear();
      contPasazer6.clear();
      contPasazer7.clear();
      contPasazer8.clear();
    });
  }

  Widget pasazer(cisloPasazer, controller, focusnode, next) {
    return Container(
      margin: EdgeInsets.only(left: 8),
      child: Row(
        children: <Widget>[
          Text(
            "$cisloPasazer. pasažér: ",
            style: TextStyle(fontSize: 14.5, fontWeight: FontWeight.w500),
          ),
          Container(
            padding: EdgeInsets.only(left: 3),
            width: 40,
            height: 25,
            decoration: BoxDecoration(
                color: Color(0xFFFFDD80),
                borderRadius: BorderRadius.all(Radius.circular(10))),
            child: Center(
              child: TextFormField(
                controller: controller,
                focusNode: focusnode,
                textInputAction: TextInputAction.next,
                onChanged: (String str) => DeleteBtn(delete: clearBoxes),
                onFieldSubmitted: (term) {
                  _fieldFocusChange(context, focusnode, next);
                },
                style: TextStyle(
                    color: Colors.black,
                    fontSize: 15,
                    fontWeight: FontWeight.w600),
                cursorWidth: 1,
                textAlign: TextAlign.center,
                textAlignVertical: TextAlignVertical.center,
                decoration: InputDecoration(
                  contentPadding: EdgeInsets.symmetric(vertical: 9),
                  border: InputBorder.none,
                  hintText: "",
                  hintStyle: TextStyle(
                    color: Color(0xFF9c9a98),
                  ),
                ),
                keyboardType: TextInputType.number,
                inputFormatters: <TextInputFormatter>[
                  WhitelistingTextInputFormatter.digitsOnly,
                  LengthLimitingTextInputFormatter(3),
                ],
              ),
            ),
          ),
          Text(" kg",
              style: TextStyle(fontSize: 14.5, fontWeight: FontWeight.w500))
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.only(
          top: MediaQuery.of(context).size.height * 0.015,
          bottom: MediaQuery.of(context).size.height * 0.015,
          left: 8,
          right: 8),
      padding: EdgeInsets.symmetric(
          vertical: MediaQuery.of(context).size.height * 0.012),
      decoration: BoxDecoration(
        color: Color(0xFFa38b5f),
        borderRadius: BorderRadius.all(Radius.circular(20)),
      ),
      child: Column(
        children: <Widget>[
          Container(
            margin: EdgeInsets.symmetric(vertical: 6, horizontal: 10),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                pasazer(1, contPasazer1, pasazer1, pasazer2),
                Container(
                  margin: EdgeInsets.only(right: 8),
                  child: Row(
                    children: <Widget>[
                      pasazer(5, contPasazer5, pasazer5, pasazer6),
                    ],
                  ),
                )
              ],
            ),
          ),
          Container(
            margin: EdgeInsets.symmetric(vertical: 6, horizontal: 10),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                pasazer(2, contPasazer2, pasazer2, pasazer3),
                Container(
                  margin: EdgeInsets.only(right: 8),
                  child: Row(
                    children: <Widget>[
                      pasazer(6, contPasazer6, pasazer6, pasazer7),
                    ],
                  ),
                )
              ],
            ),
          ),
          Container(
            margin: EdgeInsets.symmetric(vertical: 6, horizontal: 10),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                pasazer(3, contPasazer3, pasazer3, pasazer4),
                Container(
                  margin: EdgeInsets.only(right: 8),
                  child: Row(
                    children: <Widget>[
                      pasazer(7, contPasazer7, pasazer7, pasazer8),
                    ],
                  ),
                )
              ],
            ),
          ),
          Container(
            margin: EdgeInsets.symmetric(vertical: 6, horizontal: 10),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                pasazer(4, contPasazer4, pasazer4, pasazer5),
                Container(
                  margin: EdgeInsets.only(right: 8),
                  child: Row(
                    children: <Widget>[
                      Container(
                        margin: EdgeInsets.only(left: 8),
                        child: Row(
                          children: <Widget>[
                            Text(
                              "8. pasažér: ",
                              style: TextStyle(
                                  fontSize: 14.5, fontWeight: FontWeight.w500),
                            ),
                            Container(
                              padding: EdgeInsets.only(left: 3),
                              width: 40,
                              height: 25,
                              decoration: BoxDecoration(
                                  color: Color(0xFFFFDD80),
                                  borderRadius:
                                      BorderRadius.all(Radius.circular(10))),
                              child: Center(
                                child: TextFormField(
                                  controller: contPasazer8,
                                  focusNode: pasazer8,
                                  textInputAction: TextInputAction.done,
                                  onFieldSubmitted: (term) {
                                    pasazer8.unfocus();
                                  },
                                  style: TextStyle(
                                      color: Colors.black,
                                      fontSize: 15,
                                      fontWeight: FontWeight.w600),
                                  cursorWidth: 1,
                                  textAlign: TextAlign.center,
                                  textAlignVertical: TextAlignVertical.center,
                                  decoration: InputDecoration(
                                    contentPadding:
                                        EdgeInsets.symmetric(vertical: 9),
                                    border: InputBorder.none,
                                    hintText: "",
                                    hintStyle: TextStyle(
                                      color: Color(0xFF9c9a98),
                                    ),
                                  ),
                                  keyboardType: TextInputType.number,
                                  inputFormatters: <TextInputFormatter>[
                                    WhitelistingTextInputFormatter.digitsOnly,
                                    LengthLimitingTextInputFormatter(3),
                                  ],
                                  onChanged: (String str) {},
                                ),
                              ),
                            ),
                            Text(" kg",
                                style: TextStyle(
                                    fontSize: 14.5,
                                    fontWeight: FontWeight.w500))
                          ],
                        ),
                      ),
                    ],
                  ),
                )
              ],
            ),
          ),
        ],
      ),
    );
  }
}
这是我的deleteBtn.dart代码

class DeleteBtn extends StatelessWidget {
  final Function delete;
  DeleteBtn({this.delete});
  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Container(
        height: 40,
        margin: EdgeInsets.only(right: 8),
        decoration: BoxDecoration(
          color: Color(0xFF616161),
          borderRadius: BorderRadius.all(Radius.circular(20)),
        ),
        child: FlatButton(
          padding: EdgeInsets.symmetric(horizontal: 0),
          child: Text(
            "Smazat hodnoty pasažérů",
            style: TextStyle(fontSize: 10),
          ),
          onPressed: () {
            print(delete);
            delete();
          },
        ),
      ),
    );
  }
}
当我按下按钮时,我需要调用pasazeri.dart中的clearBoxes()函数
我在print(delete);中添加了onPressed:,它给了我:
The following NoSuchMethodError was thrown while handling a gesture:
The method 'call' was called on null.
Receiver: null
Tried calling: call()
所以我认为传递函数存在问题。
有谁知道我该如何解决?

最佳答案

您的代码中存在某些问题,这些问题无法实现。我会为您指出:

  • 无需在setState()中执行clearBoxes(),因为这样做就可以了。当变量的setStatevalue发生更改时,使用state反射(reflect)在小部件中。例如:在按钮上单击+1或更具体地说,添加Counter,向 Controller setState(() => contPasazer1.text = "New value")
  • 提供新文本
  • 要将function传递到窗口小部件,您应该执行delete: () => your_function_name而不是 delete: clearBoxes。您的删除是void类型,它是dart formatting error。因此,即使您通过了正确的方法
  • ,也无济于事

    让我们看一下上面实例的更正代码:
    void clearBoxed(){
      // no need of setState
      contPasazer1.clear();
      contPasazer2.clear();
      contPasazer3.clear();
      contPasazer4.clear();
      contPasazer5.clear();
      contPasazer6.clear();
      contPasazer7.clear();
      contPasazer8.clear();
    }
    
    正确将clearBoxes()传递给DeleteBtn类参数delete。阅读Pass function into a function in Dart
    // you can also do this (){ clearBoxes() }, but below is more dart way or JS way
    onChanged: (String str) => DeleteBtn(delete: () => clearBoxes())
    
    另外,我想知道为什么在DeleteBtn()中使用onChanged()?如果您想将其用作按钮,只需将其放置在此处,然后使用该按钮

    对于更简洁的方法,您可以在开始键入类似以下内容时调用clearBoxes()方法:
    onChanged: (String str) => clearBoxes()
    
    无论您想在何处使用按钮,都可以通过放置DeleteBtn来使用它,如下所示:
    Row(
     children: [
        TextFormField(
           onChanged: (String str) => clearBoxes()
        ),
        DeleteBtn(delete: () => clearBoxes())
     ]
    )
    
    考虑使用最佳实践,从长远来看,它将为您提供帮助。
    我正在显示我的代码以显示事情是如何工作的。 我刚刚使用了3个TexField和一个DeleteBtn来显示的工作原理。
    关注代码中的工作方式,特别是clearBoxes()DeleteBtn(delete: () => clearBoxes())
    class _MyHomePageState extends State<MyHomePage> {
      TextEditingController contPasazer1 = TextEditingController();
      TextEditingController contPasazer2 = TextEditingController();
      TextEditingController contPasazer3 = TextEditingController();
    
      // no need of setState()
      void clearBoxes() {
        contPasazer1.clear();
        contPasazer2.clear();
        contPasazer3.clear();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Container(
            height: double.infinity,
            width: double.infinity,
            padding: EdgeInsets.symmetric(horizontal: 20.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                TextFormField(controller: contPasazer1),
                SizedBox(height: 20.0),
                TextFormField(controller: contPasazer2),
                SizedBox(height: 20.0),
                TextFormField(controller: contPasazer3),
                SizedBox(height: 20.0),
                // Your delete button from another class
                DeleteBtn(delete: () => clearBoxes())
              ]
            )
          )
        );
      }
    }
    
    // Your other class
    class DeleteBtn extends StatelessWidget {
      final Function delete;
      DeleteBtn({this.delete});
      @override
      Widget build(BuildContext context) {
        return Expanded(
          child: Container(
            height: 40,
            margin: EdgeInsets.only(right: 8),
            decoration: BoxDecoration(
              color: Color(0xFF616161),
              borderRadius: BorderRadius.all(Radius.circular(20)),
            ),
            child: FlatButton(
              padding: EdgeInsets.symmetric(horizontal: 0),
              child: Text(
                "Smazat hodnoty pasažérů",
                style: TextStyle(fontSize: 10),
              ),
              onPressed: () {
                print(delete);
                delete();
              },
            ),
          ),
        );
      }
    }
    
    结果
    免责声明:不要看UI,我要请您看一下功能。我仅使用了DeleteBtn,但布局不理想,因此深表歉意。
    flutter - 如何在两个小部件(文件)之间传递数据?-LMLPHP

    关于flutter - 如何在两个小部件(文件)之间传递数据?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63159092/

    10-09 01:27