如何在两个小部件(文件)之间传递数据?

时间:2020-07-29 17:21:08

标签: flutter dart flutter-layout

我正在构建一个Flutter应用程序,我需要将功能传递给其他小部件。 Screenshot of my app for better understading

我有这8个TextFormField,其中包含值。 当我按下灰色按钮“ 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()

所以我认为传递函数存在问题。

有人知道我该如何解决吗?

2 个答案:

答案 0 :(得分:2)

将此行添加到您的代码中:

import 'pasazeri.dart' as paz(..in ur deletebtn.dart)

然后,在onPressed()中添加以下行:

paz.PasazeriState().clearBoxes();

OR

  1. 在您的pasazeri.dart中,在“覆盖”上方添加此行。

Pasazeri(this.clearbox);

  final bool clearbox;

  1. 将您的clearBoxes函数更改为此-
void clearbox(){

bool k= widget.clearbox;//..put it in set state.

If(k){
//Delete boxes
}Else{
//Do smthng
}

}//Clearbox closes
  1. 现在,在您的deletebtn.dart中的onPressed()中,写上这个
Pasazeri(true);

莱姆知道这是否行得通,我认为应该行得通。

答案 1 :(得分:1)

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

  • 无需在您的setState()中进行clearBoxes(),因为那样就可以了。当变量setState的{​​{1}}发生变化时,使用value来反映在小部件中。例如:添加{ {1}},只需按一下state的按钮,即可为您的控制器+1
  • 提供新文本
  • 要将Counter传递到小部件,您应该执行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()。请阅读Pass function into a function in Dart

DeleteBtn

我也想知道,为什么在delete中使用// you can also do this (){ clearBoxes() }, but below is more dart way or JS way onChanged: (String str) => DeleteBtn(delete: () => clearBoxes()) ?如果您想将其用作按钮,只需简单地放置在那里,然后使用按钮

每次您开始在指定的DeleteBtn()中书写时,都会调用

onChanged()。我建议这不是最佳实践

对于更简洁的方法,当您开始键入以下内容时,只需调用方法onChanged()

TextFormField

无论您想在何处使用按钮,都可以通过放置clearBoxes()来使用它,如下所示:

onChanged: (String str) => clearBoxes()

考虑使用最佳做法,从长远来看将为您提供帮助。

我正在显示我的代码以显示事情的运行方式。 我刚刚使用了3个TexField和一个DeleteBtn来显示其工作原理

关注代码中事物的工作方式,特别是DeleteBtnRow( children: [ TextFormField( onChanged: (String str) => clearBoxes() ), DeleteBtn(delete: () => clearBoxes()) ] )

clearBoxes()

结果

免责声明::不要看用户界面,我要请您看一下功能。我仅使用了您的DeleteBtn(delete: () => clearBoxes()),但布局不理想,因此深表歉意。

Result