본문 바로가기
expert

Flutter의 화면 간 데이터 전달

by RWriter 2023. 1. 28.
반응형

질문 제목:

Flutter의 화면 간 데이터 전달

질문 내용:

Flutter를 배우면서 내비게이션을 접하게 되었습니다. Android의 Activity 간에 데이터를 전달하고 iOS의 View Controller 간에 데이터를 전달하는 것과 유사 하게 화면 간에 데이터를 전달하고 싶습니다 . Flutter에서는 어떻게 하나요?

관련 질문:

해결 답변:

이 답변은 데이터 전달과 데이터 전달을 모두 다룹니다. Android 활동 및 iOS ViewController와 달리 Flutter의 다양한 화면은 위젯일 뿐입니다. 이들 사이를 탐색하려면 경로라고 하는 항목을 생성 Navigator하고 스택에서 경로를 푸시 및 팝하는 데 사용합니다.

데이터를 다음 화면으로 전달

여기에 이미지 설명 입력

다음 화면으로 데이터를 보내려면 다음 작업을 수행합니다.

  1. SecondScreen생성자가 보내려는 데이터 유형에 대한 매개변수를 받도록 합니다 . 이 특정 예에서 데이터는 String값으로 정의되며 여기에서 로 설정됩니다 this.text.

    class SecondScreen extends StatelessWidget {
      final String text;
      SecondScreen({Key key, @required this.text}) : super(key: key);
    
      ...
    
  2. 그런 다음 위젯에서 를 사용하여 Navigator경로 FirstScreen를 위젯으로 푸시합니다 SecondScreen. 생성자에 매개변수로 보내려는 데이터를 넣습니다.

    Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => SecondScreen(text: 'Hello',),
        ));
    

에 대한 전체 코드 main.dart는 다음과 같습니다.

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Flutter',
    home: FirstScreen(),
  ));
}

class FirstScreen extends StatefulWidget {
  @override
  _FirstScreenState createState() {
    return _FirstScreenState();
  }
}

class _FirstScreenState extends State<FirstScreen> {

  // this allows us to access the TextField text
  TextEditingController textFieldController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('First screen')),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [

          Padding(
            padding: const EdgeInsets.all(32.0),
            child: TextField(
              controller: textFieldController,
              style: TextStyle(
                fontSize: 24,
                color: Colors.black,
              ),
            ),
          ),

          RaisedButton(
            child: Text(
              'Go to second screen',
              style: TextStyle(fontSize: 24),
            ),
            onPressed: () {
              _sendDataToSecondScreen(context);
            },
          )

        ],
      ),
    );
  }

  // get the text in the TextField and start the Second Screen
  void _sendDataToSecondScreen(BuildContext context) {
    String textToSend = textFieldController.text;
    Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => SecondScreen(text: textToSend,),
        ));
  }
}

class SecondScreen extends StatelessWidget {
  final String text;

  // receive data from the FirstScreen as a parameter
  SecondScreen({Key key, @required this.text}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Second screen')),
      body: Center(
        child: Text(
          text,
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }
}

데이터를 이전 화면으로 다시 전달

여기에 이미지 설명 입력

데이터를 다시 전달할 때 다음 작업을 수행해야 합니다.

  1. 에서 the FirstScreen를 사용하여 메서드 Navigator를 푸시(시작)하고 완료되면 반환할 결과를 기다립니다.SecondScreenasync

    final result = await Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => SecondScreen(),
        ));
    
  2. 에서 SecondScreen를 팝할 때 매개변수로 다시 전달할 데이터를 포함합니다 Navigator.

    Navigator.pop(context, 'Hello');
    
  3. 그런 다음 의지에서 FirstScreen완료 await하고 결과를 사용할 수 있습니다.

    setState(() {
      text = result;
    });
    

참조 를 위한 전체 코드는 다음과 같습니다 main.dart.

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Flutter',
    home: FirstScreen(),
  ));
}

class FirstScreen extends StatefulWidget {
  @override
  _FirstScreenState createState() {
    return _FirstScreenState();
  }
}

class _FirstScreenState extends State<FirstScreen> {

  String text = 'Text';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('First screen')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [

            Padding(
              padding: const EdgeInsets.all(32.0),
              child: Text(
                text,
                style: TextStyle(fontSize: 24),
              ),
            ),

            RaisedButton(
              child: Text(
                'Go to second screen',
                style: TextStyle(fontSize: 24),
              ),
              onPressed: () {
                _awaitReturnValueFromSecondScreen(context);
              },
            )

          ],
        ),
      ),
    );
  }

  void _awaitReturnValueFromSecondScreen(BuildContext context) async {

    // start the SecondScreen and wait for it to finish with a result
    final result = await Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => SecondScreen(),
        ));

    // after the SecondScreen result comes back update the Text widget with it
    setState(() {
      text = result;
    });
  }
}

class SecondScreen extends StatefulWidget {
  @override
  _SecondScreenState createState() {
    return _SecondScreenState();
  }
}

class _SecondScreenState extends State<SecondScreen> {
  // this allows us to access the TextField text
  TextEditingController textFieldController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Second screen')),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [

          Padding(
            padding: const EdgeInsets.all(32.0),
            child: TextField(
              controller: textFieldController,
              style: TextStyle(
                fontSize: 24,
                color: Colors.black,
              ),
            ),
          ),

          RaisedButton(
            child: Text(
              'Send text back',
              style: TextStyle(fontSize: 24),
            ),
            onPressed: () {
              _sendDataBack(context);
            },
          )

        ],
      ),
    );
  }

  // get the text in the TextField and send it back to the FirstScreen
  void _sendDataBack(BuildContext context) {
    String textToSendBack = textFieldController.text;
    Navigator.pop(context, textToSendBack);
  }
}
반응형

댓글