Flutter GetX 传递数据到另一个页面

Flutter GetX pass data to another page

我有一个 flutter 应用程序,我在其中使用屏幕中的文本表单字段捕获数据。我有第二个屏幕,我想在其中显示我从第一个屏幕的文本表单字段中捕获的数据。

但首先我想将其从第二屏幕控制器打印到终端,然后查看已通过的内容。我尝试使用 GetX 导航并通过,但出现此错误

The method '[]' was called on null.
Receiver: null
Tried calling: [](0)

这是我用来获取数据作为输入的文本表单域

TextFormField(
                      controller: controller._phoneNumberController,
                      keyboardType: TextInputType.text,
                      validator: (value) => validatePhoneNumber(value!),
                      style: TextStyle(
                        color: accentColor,
                        fontSize: 15,
                        fontFamily: 'PoppinsRegular',
                      ),
                      decoration: InputDecoration(
                        hintText: "Phone Number",
                        hintStyle: TextStyle(
                            fontSize: 14,
                            color: Colors.black45,
                            fontWeight: FontWeight.w500),
                        fillColor: Color(0xffEBEDF4),
                        filled: true,
                        border: InputBorder.none,
                        focusedBorder: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(8.0),
                          borderSide: BorderSide(
                            color: Color(0xff1D275C),
                          ),
                        ),
                        enabledBorder: OutlineInputBorder(
                          borderRadius: BorderRadius.circular(8.0),
                          borderSide: BorderSide(
                            color: formFieldColor,
                            width: 2.0,
                          ),
                        ),
                      ),
                    ),

这是我用来发送数据到下一页的方法

GestureDetector(
                              onTap: () {
                                Get.to(SecondPage(), arguments: [
                                  controller._phoneNumberController.text
                                ]);
                              },
                              child: Container(
                                height: 40,
                                width: double.infinity,
                                decoration: BoxDecoration(
                                  color: Color(0xffEF5E41),
                                ),
                                child: Center(
                                  child: Row(
                                    mainAxisAlignment: MainAxisAlignment.end,
                                    children: [
                                      Padding(
                                        padding:
                                            const EdgeInsets.only(right: 130),
                                        child: Text(
                                          "Proceed",
                                          style: TextStyle(
                                            color: Color(0xffFCFCFC),
                                            fontSize: 14,
                                            fontWeight: FontWeight.w500,
                                          ),
                                        ),
                                      ),
                                      Padding(
                                        padding:
                                            const EdgeInsets.only(right: 16),
                                        child: Icon(
                                          Icons.arrow_forward_ios,
                                          color: Color(0xffFCFCFC),
                                        ),
                                      )
                                    ],
                                  ),
                                ),
                              ),
                            ),

这是我尝试打印从第一页发送的数据的地方

  dynamic argumentData = Get.arguments;

  @override
  void onInit() {
    print(argumentData[0]);
    super.onInit();
  }

我该如何解决这个问题

您需要使用表单小部件包装您的 TextFormField。 然后创建一个 GlobalKey 类型的表单键,并在 Stateful widget 的 initState 函数中对其进行初始化。

Form 小部件的 key 属性 中,使用此 GlobalKey。

在 TextFormField 小部件中,使用 onSaved 属性 传递函数以将表单字段的值保存在您想要的任何位置。只有在您调用 onSaved 之后,数据才会保存在任何地方,因此您需要使用它来将数据保存到 Getx 控制器中的 _phoneNumberController 变量。

现在,数据没有被保存,控制器为空,这就是为什么当你调用 argumentData 时它会抛出异常。它的值为 null 因为 _phoneNumberContoller 文本值也为空。

抱歉,格式错误,我正在使用我的 phone 来输入。

我知道你在这里有一个可以接受的答案,但只是想用一种不同的、可以说更简单的方式来插话,这种方式不涉及传递参数或键。

GetX class 中的任何 TextEditingController 都可以从任何地方访问。

添加侦听器并将该值存储到变量中。

class Controller extends GetxController {
  final textController = TextEditingController();

  RxString controllerText = ''.obs;

  @override
  void onInit() {
    super.onInit();
    textController.addListener(() {
      controllerText.value = textController.text;
    });
  }
}

您可以使用几个简单的页面进行测试。

class Page1 extends StatelessWidget {
  static const id = '/page1';
  final controller = Get.put(Controller());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            TextField(controller: controller.textController),
            ElevatedButton(
              onPressed: () => Get.toNamed(Page2.id),
              child: Text('Go to page 2'),
            ),
          ],
        ),
      ),
    );
  }
}

class Page2 extends StatelessWidget {
  static const id = '/page2';

  @override
  Widget build(BuildContext context) {
    final controller = Get.find<Controller>();
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Center(
            // Obx technically isn't needed for this example because 
            // Page2 builds after the value is updated
            child: Obx(
              () => Text(controller.controllerText
                  .value), 
            ),
          ),
          ElevatedButton(
            onPressed: () => Get.back(),
            child: Text('Go to page 1'),
          ),
        ],
      ),
    );
  }
}