티스토리 뷰
새로운 화면으로 이동할 때 데이터를 전달하는 경우가 종종 있습니다. 예를 들어, 사용자가 항목을 탭할 때 해당 항목에 대한 정보를 새 화면에 전달할 수 있습니다.
기억하세요: 화면은 단순히 위젯입니다. 이 예제에서는 할 일 목록을 생성하고, 할 일을 탭하면 해당 할 일에 대한 정보를 표시하는 새 화면(위젯)으로 이동합니다.
이 문서는 다음 단계를 사용합니다:
- 할 일 클래스를 정의합니다.
- 할 일 목록을 표시합니다.
- 할 일 정보를 표시할 수 있는 세부 화면을 만듭니다.
- 데이터와 함께 세부 화면으로 이동합니다.
1. 할 일 클래스 정의하기
먼저, 할 일을 간단하게 표현할 방법이 필요합니다. 이 예제에서는 제목과 설명 두 가지 데이터를 포함하는 클래스를 만듭니다.
class Todo {
final String title;
final String description;
const Todo(this.title, this.description);
}
2. 할 일 목록 생성하기
두 번째로, 할 일 목록을 표시합니다. 이 예제에서는 20개의 할 일을 생성하고 ListView
를 사용하여 이를 표시합니다.
할 일 목록 생성
final todos = List.generate(
20,
(i) => Todo(
'Todo $i',
'A description of what needs to be done for Todo $i',
),
);
ListView를 사용하여 할 일 목록 표시
ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
);
},
)
여기까지 잘 진행되었다면, 20개의 할 일을 생성하고 ListView에 표시될 것입니다.
3. 할 일 목록을 표시할 화면 생성하기
이 작업을 위해 StatelessWidget
을 생성합니다. 이를 TodosScreen
이라고 부르겠습니다. 이 페이지(화면)의 내용은 런타임 동안 변경되지 않으므로 TodosScreen 위젯 내에 할 일 목록을 필요로 합니다.
build()
메서드에서 반환할 위젯의 본문으로 ListView.builder
를 전달합니다. 이렇게 하면 화면에 목록이 렌더링 됩니다.
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'),
),
// `ListView.builder`를 전달합니다.
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
);
},
),
);
}
}
Flutter의 기본 스타일링을 사용하면, 나중에 하고 싶은 작업에 대해 걱정할 필요 없이 바로 시작할 수 있습니다!
4. 할 일 정보를 표시할 세부 화면 생성하기
이제 두 번째 화면을 만듭니다. 화면의 제목은 할 일의 제목을 포함하고, 화면의 본문은 할 일의 설명을 보여줍니다.
세부 화면은 일반 StatelessWidget
이므로 세부 화면을 생성 시에 Todo
를 입력하도록 요구합니다. 그런 다음 주어진 Todo
를 사용하여 UI를 빌드합니다.
class DetailScreen extends StatelessWidget {
// 생성자에서 `Todo`를 요구합니다.
const DetailScreen({super.key, required this.todo});
// `Todo`를 보관할 필드를 선언합니다.
final Todo todo;
@override
Widget build(BuildContext context) {
// `Todo`를 사용하여 UI를 생성합니다.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
5. 데이터와 함께 세부 화면으로 이동하기
DetailScreen
이 준비되었으므로, 이제 네비게이션을 수행할 준비가 되었습니다. 이 예제에서는 사용자가 할 일 목록에서 항목을 탭할 때 DetailScreen
으로 이동하고, Todo
를 DetailScreen
에 전달합니다.
TodosScreen
에서 사용자의 탭을 캡처하려면 ListTile
위젯의 onTap()
콜백을 작성합니다. onTap()
콜백 내에서 Navigator.push()
메서드를 사용합니다.
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// 사용자가 ListTile을 탭하면 DetailScreen으로 이동합니다.
// 현재 todo를 전달합니다.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
)
완성 코드
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),
// 사용자가 ListTile을 누르면, 상세 화면으로 이동한다.
// 상세 화면을 만들 뿐만 아니라 현재 할 일을 전달한다.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
);
}
}
class DetailScreen extends StatelessWidget {
// 생성자는 할 일(Todo)을 필요로 한다.
const DetailScreen({super.key, required this.todo});
// Todo를 가지는 필드를 선언한다.
final Todo todo;
@override
Widget build(BuildContext context) {
// UI를 만들기 위해서 Todo를 사용한다.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
RouteSettings를 사용하여 인수 전달하기
위에서 사용한 1, 2 단계를 동일하게 사용합니다.
인수를 추출하여 표시하는 세부 화면 생성하기
다음으로, Todo
에서 제목과 설명을 추출하여 표시하는 세부 화면을 만듭니다. Todo
에 접근하려면 ModalRoute.of()
메서드를 사용합니다. 이 메서드는 인수가 있는 현재 라우트를 반환합니다.
class DetailScreen extends StatelessWidget {
const DetailScreen({super.key});
@override
Widget build(BuildContext context) {
final todo = ModalRoute.of(context)!.settings.arguments as Todo;
// `Todo`를 사용하여 UI를 생성합니다.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
인수를 전달하여 세부 화면으로 내비게이션 하기
마지막으로, 사용자가 ListTile
위젯을 탭할 때 Navigator.push()
를 사용하여 DetailScreen
으로 이동합니다. 인수를 RouteSettings
의 일부로 전달합니다. DetailScreen
은 RouteSettings로 전달된 인수를 사용합니다.
ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
// 사용자가 ListTile을 탭하면 DetailScreen으로 이동합니다.
// DetailScreen을 생성할 뿐만 아니라 현재 todo를
// 해당 화면으로 전달합니다.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DetailScreen(),
// 인수를 RouteSettings의 일부로 전달합니다.
// DetailScreen은 이러한 설정에서 인수를 읽습니다.
settings: RouteSettings(
arguments: todos[index],
),
),
);
},
);
},
)
완성 코드
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),
// 사용자가 ListTile을 탭하면 DetailScreen으로 이동합니다.
// DetailScreen을 생성할 뿐만 아니라 현재 todo를
// 해당 화면으로 전달합니다.
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const DetailScreen(),
// 인수를 RouteSettings의 일부로 전달합니다.
// DetailScreen은 이러한 설정에서 인수를 읽습니다.
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;
// Todo를 사용하여 UI를 생성합니다.
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}
'Flutter > 네비게이션' 카테고리의 다른 글
플러터] 네비게이션과 라우팅 - 화면에 드로어(drawer) 추가하기 (0) | 2024.06.30 |
---|---|
플러터] 네비게이션과 라우팅 - 화면에서 데이터 반환하기 (0) | 2024.06.30 |
플러터] 네비게이션과 라우팅 - 새로운 화면으로 이동하고 돌아오기 (0) | 2024.06.29 |
플러터] 네비게이션과 라우팅 - 탭(Tap) 작업하기 (0) | 2024.06.29 |
플러터] 네비게이션과 라우팅 - 개요 (0) | 2024.06.29 |