티스토리 뷰

Flutter 애플리케이션에서 화면 간 데이터를 전달하는 기능은 필수적입니다. 특히 다중 화면 앱을 개발하는 과정에서, 한 화면에서 다른 화면으로 정보를 전달하는 것은 사용자 경험을 향상시키는 데 큰 역할을 합니다. 이번 글에서는 Flutter에서 데이터를 전달하는 방법에 대해 단계별로 살펴보고, 실제 구현 예제를 통해 쉽게 이해할 수 있도록 안내합니다.

참고. Send data to a new screen

데이터를 전달해야 하는 이유

Flutter 앱에서 화면 간 데이터를 전달해야 하는 경우는 다양합니다:

  • 로그인 화면에서 사용자 정보를 대시보드 화면으로 전달
  • 상품 리스트에서 선택한 상품 정보를 상세 페이지로 전달
  • 설정 화면에서 사용자 선택 사항을 저장 후 반영

데이터 전달을 효과적으로 처리하면 코드 유지 보수가 쉬워지고, 앱 성능도 최적화됩니다.

Navigator를 활용한 데이터 전달 방법

Navigator의 역할

Navigator는 Flutter에서 화면을 이동하거나 데이터를 전달하는 데 사용되는 핵심적인 위젯입니다. push()pop() 메서드를 통해 새로운 화면을 생성하거나 기존 화면으로 돌아갈 수 있습니다.

Navigator로 데이터 전달하기

Navigator의 push() 메서드와 함께 MaterialPageRoute를 사용해 데이터를 전달할 수 있습니다.

Flutter에서 데이터 전달 구현: 단계별 가이드

1. 첫 번째 화면: 데이터 준비

첫 번째 화면에서 데이터를 생성하고, Navigator를 사용해 두 번째 화면으로 전달합니다.

import 'package:flutter/material.dart';

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('First Screen')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => SecondScreen(data: 'Hello, Flutter!'),
              ),
            );
          },
          child: Text('Go to Second Screen'),
        ),
      ),
    );
  }
}

2. 두 번째 화면: 데이터 수신

두 번째 화면에서는 전달된 데이터를 받습니다. 이를 위해 생성자(constructor)를 사용합니다.

class SecondScreen extends StatelessWidget {
  final String data;

  SecondScreen({required this.data});

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

데이터를 반환하는 방법

두 번째 화면에서 데이터를 첫 번째 화면으로 반환하려면 Navigator.pop()을 사용합니다.

데이터 반환 구현

  1. 두 번째 화면에서 데이터 설정 및 반환:
  2. Navigator.pop(context, 'Returned Data');
  3. 첫 번째 화면에서 반환 데이터 수신:
  4. onPressed: () async { final result = await Navigator.push( context, MaterialPageRoute( builder: (context) => SecondScreen(data: 'Hello again!'), ), ); print('Returned Data: $result'); }

데이터를 전달하는 주요 팁

1. 데이터 타입 정의

전달하려는 데이터의 타입(String, List, Map 등)을 명확히 정의합니다.

2. 상태 관리 활용

데이터 전달이 복잡해질 경우, Provider, Riverpod, Bloc 같은 상태 관리 라이브러리를 활용하세요.

3. 테스트 케이스 작성

화면 간 데이터 전달이 제대로 작동하는지 확인하기 위해 테스트 코드를 작성하세요.


요약: Flutter 데이터 전달의 핵심 정리

Flutter에서 데이터를 전달하는 방법은 직관적이고 간단합니다. 다음을 기억하세요:

  • Navigator.push()로 데이터 전달
  • 생성자(constructor)로 데이터 수신
  • Navigator.pop()으로 데이터 반환

효율적인 데이터 전달은 앱의 구조와 유지 보수성에 큰 영향을 미칩니다. 위의 방법을 따라 구현해 보세요!

 

import 'package:flutter/material.dart';

class Todo {
  final String title;
  final String description;

  const Todo(this.title, this.description);
}

void main() {
  runApp(
    MaterialApp(
      title: 'Passing Data',
      home: TodosScreen(
        todos: List.generate(
          20,
          (i) => Todo(
            'Todo $i',
            'A description of what needs to be done for Todo $i',
          ),
        ),
      ),
    ),
  );
}

class TodosScreen extends StatelessWidget {
  const TodosScreen({super.key, required this.todos});

  final List<Todo> todos;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Todos'),
      ),
      body: ListView.builder(
        itemCount: todos.length,
        itemBuilder: (context, index) {
          return ListTile(
            title: Text(todos[index].title),
            // When a user taps the ListTile, navigate to the DetailScreen.
            // Notice that you're not only creating a DetailScreen, you're
            // also passing the current todo through to it.
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => const DetailScreen(),
                  // Pass the arguments as part of the RouteSettings. The
                  // DetailScreen reads the arguments from these settings.
                  settings: RouteSettings(
                    arguments: todos[index],
                  ),
                ),
              );
            },
          );
        },
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final todo = ModalRoute.of(context)!.settings.arguments as Todo;

    // Use the Todo to create the UI.
    return Scaffold(
      appBar: AppBar(
        title: Text(todo.title),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Text(todo.description),
      ),
    );
  }
}