如何在结果中接受多个变量?

how to accept multiple variables in result?

我使用 pop() 将一个参数从一个屏幕传递到前一个屏幕。当我传递一个变量时,一切都很好,但是当我传递多个变量时,应用程序无法运行。 我该如何解决这个问题并将 inputText 和两个变量 _privacy 和 _terms_of_use 的值传递给我并输出它们?如何将它们添加到 pop() 并作为结果在 setState 中接收? 我的屏幕有 arg:

class TextScreen extends StatefulWidget {
  const TextScreen({Key? key}) : super(key: key);

  @override
  State<TextScreen> createState() => _TextScreenState();
}

class _TextScreenState extends State<TextScreen> {
  // initial values for checkboxes
  bool _privacy = false;
  bool _termsOfUse = false;

  // text controller for message input
  TextEditingController textController = TextEditingController();

  @override
  void dispose() {
    textController.dispose();
    super.dispose();
  }

  void _getResult(BuildContext context) {
    String inputText = textController.text;
    Navigator.of(context).pop(inputText);
  }

  @override
  Widget build(BuildContext context) {
    void _onChangePrivacy(value) {
      setState(() {
        _privacy = value!;
      });
    }

    void _onChangeTermsOfUse(value) {
      setState(() {
        _termsOfUse = value!;
      });
    }

    return Scaffold(
      appBar: AppBar(
        title: const Text('Enter data'),
      ),
      body: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              TextField(
                controller: textController,
                decoration: const InputDecoration(labelText: 'Message'),
              ),
              const SizedBox(height: 20),
              CheckboxListTile(
                title: const Text('Privacy'),
                controlAffinity: ListTileControlAffinity.leading,
                value: _privacy,
                onChanged: (value) {
                  _onChangePrivacy(value);
                },
                contentPadding: EdgeInsets.zero,
              ),
              CheckboxListTile(
                title: const Text('Terms of use'),
                controlAffinity: ListTileControlAffinity.leading,
                value: _termsOfUse,
                onChanged: (value) {
                  _onChangeTermsOfUse(value);
                },
                contentPadding: EdgeInsets.zero,
              ),
              ElevatedButton(
                  onPressed: () {
                    _getResult(context);
                  },
                  child: const Text('Display result'))
            ],
          )),
    );
  }
}

我的结果屏幕:

class ResultScreen extends StatefulWidget {
  @override
  State<ResultScreen> createState() => _ResultScreenState();
}

class _ResultScreenState extends State<ResultScreen> {
  String? _valueText = '';

  @override
  Widget build(BuildContext context) {
    // navigation to next screen
    void _navToNextScreen(BuildContext context) async {
      final result = await Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => const TextScreen()),
      );
      setState(() {
        _valueText = result;
      });
    }

    return Scaffold(
      appBar: AppBar(
        title: const Text('Results'),
      ),
      body: Center(
          child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton(
              onPressed: () {
                _navToNextScreen(context);
              },
              child: const Text('Enter data')),
          const SizedBox(height: 50),
          Text('Message: $_valueText'),
          const SizedBox(height: 20),
          Text('Checkboxes: '),
        ],
      )),
    );
  }
}

如果我们看一下 pop 方法的实现,它看起来像这样:

  @optionalTypeArgs
  static void pop<T extends Object?>(BuildContext context, [ T? result ]) {
    Navigator.of(context).pop<T>(result);
  }

这意味着我们可以选择传递一个通用对象 (T? result)。 在您的情况下,传递包含多个对象的 List 是最简单的解决方案。

调用 pop 的屏幕可能如下所示:

 Navigator.of(context).pop([inputText, inputText2]);

你的接收屏幕可以做这样的事情:

 final results = await Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => const TextScreen()),
      );
 var textOne = results[0];
 var textTwo = results[1];
 ...

您可以像这样在数组中传递它们:

List<String> data = ['str1', 'str2', 'str3'];
Navigator.of(context).pop(data);

然后像那样接收它们:

List<String> result = await Navigator.push(
   context,
   MaterialPageRoute(builder: (context) => const TextScreen()),
);
setState(() {
   _value1 = result[0];
   _value2 = result[1];
   _value3 = result[2];
});