티스토리 뷰

플러터에서 화면을 push, pop하면서 데이터를 넘겨받는 방법

 

1. push 할 때

(1) 새로운 화면(SecondScreen)에 필수 파라미터를 설정하여 값을 넘기는 방법

SecondScreen에 inputString이라는 필수 파라미터를 설정하여 push할 때 해당 파라미터 값을 넘기도록 함

onPressed: () {
  Navigator.push(
  	context,
    CupertinoPageRoute(
      builder: (context) => SecondScreen(inputString: _textEditingController.text),
    ),
  );
},

 

전체코드

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo)),
      home: const FirstScreen(),
    );
  }
}


//첫 번째 화면
class FirstScreen extends StatefulWidget {
  const FirstScreen({super.key});

  @override
  State<FirstScreen> createState() => _FirstScreenState();
}

class _FirstScreenState extends State<FirstScreen> {
  final TextEditingController _textEditingController = TextEditingController();
  
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _textEditingController.dispose();
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('첫 번째 화면'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            SizedBox(
              width: 250,
              child: TextField(
                controller: _textEditingController,
              ),
            ),
            OutlinedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  CupertinoPageRoute(
                    //⭐️⭐️⭐️
                    builder: (context) => SecondScreen(
                      inputString: _textEditingController.text,
                    ),
                  ),
                );
              },
              child: const Text('두 번째 화면으로'),
            )
          ],
        ),
      ),
    );
  }
}


//두 번째 화면
class SecondScreen extends StatefulWidget {
  const SecondScreen({super.key, required this.inputString});

  //⭐️⭐️⭐️
  final String inputString;

  @override
  State<SecondScreen> createState() => _SecondScreenState();
}

class _SecondScreenState extends State<SecondScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('두 번째 화면'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('넘어온 값: ${widget.inputString}'),
            OutlinedButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              child: const Text('첫 번째 화면으로'),
            ),
          ],
        ),
      ),
    );
  }
}

 

 


 

(2) RoutSettings의 arguments 파라미터를 이용하는 방법

 

MaterialPageRoute 클래스에는 RouteSettings 타입의 settings 파라미터가 있는데, 이 파라미터는 Object? 타입을 가진 arguments를 받음. 

Object 타입이라는 말은 기본 데이터 유형인 int, double, bool, String뿐만 아니라 list, map, class와 같은 더 복잡한 유형도 포함된다 = 즉, 모든 유형의 값을 넣을 수 있다고 생각하면 됨!

 

 

넘기고자 하는 값을 arguments 파라미터에 인자로 넣어주면 됨

Navigator.push(
  context,
  CupertinoPageRoute(builder: (context) => const SecondScreen(),
    //⭐️⭐️⭐️
    settings:RouteSettings(arguments: _textEditingController.text),
  ),
);

 

받을 때는 받는 화면의 build 메서드 아래에서 받아주면 됨

@override
  Widget build(BuildContext context){
    final argumentsString = ModalRoute.of(context)!.settings.arguments as String;
    
    return Widget();
  }

 


전체코드

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo)),
      home: const FirstScreen(),
    );
  }
}

//첫 번째 화면
class FirstScreen extends StatefulWidget {
  const FirstScreen({super.key});

  @override
  State<FirstScreen> createState() => _FirstScreenState();
}

class _FirstScreenState extends State<FirstScreen> {
  final TextEditingController _textEditingController = TextEditingController();
  
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _textEditingController.dispose();
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('첫 번째 화면'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            SizedBox(
              width: 250,
              child: TextField(
                controller: _textEditingController,
              ),
            ),
            OutlinedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  CupertinoPageRoute(
                    builder: (context) => const SecondScreen(),
                    ///⭐️⭐️⭐️ 데이터 넘기는 곳
                    settings:
                        RouteSettings(arguments: _textEditingController.text),
                  ),
                );
              },
              child: const Text('두 번째 화면으로'),
            )
          ],
        ),
      ),
    );
  }
}

//두 번째 화면
class SecondScreen extends StatefulWidget {
  const SecondScreen({super.key});

  @override
  State<SecondScreen> createState() => _SecondScreenState();
}

class _SecondScreenState extends State<SecondScreen> {
  @override
  Widget build(BuildContext context) {
  	//⭐️⭐️⭐️ 데이터 받는 곳
    final argumentsString =
        ModalRoute.of(context)!.settings.arguments as String;
    return Scaffold(
      appBar: AppBar(
        title: const Text('두 번째 화면'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('넘어온 값: $argumentsString'),
            OutlinedButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              child: const Text('첫 번째 화면으로'),
            ),
          ],
        ),
      ),
    );
  }
}

 

 

 

 


2. pop 할 때

pop할 때도 보내고자 하는 값을 보냄

onPressed: () {
  Navigator.of(context).pop(_textEditingController.text);
},

 

해당 값은 네비게이터를 push한 곳에서 받을 수 있기 때문에, 값이 넘어올 때까지 기다려줘야 함 (await & async)

하지만, 결과값이 null일 수도 있기 때문에 항상 null check를 해주고 사용해야 함

onPressed: () async {
  String? result = await Navigator.push(
  context,
    CupertinoPageRoute(
      builder: (context) => const SecondScreen(),
    ),
  );

  //결과값이 null인지 확인
  if (result != null) {
    setState(() {
      dataFromSecondScreen = result;
    });
  }
},

 

전체코드

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo)),
      home: const FirstScreen(),
    );
  }
}

//첫 번째 화면
class FirstScreen extends StatefulWidget {
  const FirstScreen({super.key});

  @override
  State<FirstScreen> createState() => _FirstScreenState();
}

class _FirstScreenState extends State<FirstScreen> {
  String dataFromSecondScreen = '없음';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('첫 번째 화면'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('넘어온 값: $dataFromSecondScreen'),
            OutlinedButton(
              onPressed: () async {
				//⭐️⭐️⭐️ 데이터 넘겨받기. 값을 기다려줘야 하기 때문에 await-async 사용
                String? result = await Navigator.push(
                  context,
                  CupertinoPageRoute(
                    builder: (context) => const SecondScreen(),
                  ),
                );

                if (result != null) {
                  setState(() {
                    dataFromSecondScreen = result;
                  });
                }
              },
              child: const Text('두 번째 화면으로'),
            )
          ],
        ),
      ),
    );
  }
}

//두 번째 화면
class SecondScreen extends StatefulWidget {
  const SecondScreen({super.key});

  @override
  State<SecondScreen> createState() => _SecondScreenState();
}

class _SecondScreenState extends State<SecondScreen> {
  final TextEditingController _textEditingController = TextEditingController();

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _textEditingController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('두 번째 화면'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SizedBox(
              width: 250,
              child: TextField(
                controller: _textEditingController,
              ),
            ),
            OutlinedButton(
              onPressed: () {
                //⭐️⭐️⭐️ pop하면 데이터 리턴하기
                Navigator.of(context).pop(_textEditingController.text);
              },
              child: const Text('첫 번째 화면으로'),
            ),
          ],
        ),
      ),
    );
  }
}

 

 

자세한 내용은 아래 공식 사이트에서도 확인 가능

 

Send data to a new screen

How to pass data to a new route.

docs.flutter.dev

 

 

Return data from a screen

How to return data from a new screen.

docs.flutter.dev

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크