❮
[Flutter] 8. 화면 전환 (Routes, Navigation)
20190919
Flutter에서의 화면. 즉, 안드로이드에서의 Activity, iOS에서의 ViewController를 route
라고 합니다.
Navigator
를 이용해서 새로운 route로 이동할 수 있습니다.
Navigator
는 스택 구조를 이용합니다.
새로운 화면으로 이동하려면 Navigator.push() 메소드를 이용하고, 다시 Navigator.pop() 을 이용해서 기존 화면으로 돌아갑니다.
push() 메소드의 두 번째 매개변수는 MaterialPageRoute가 옵니다.
MPR 내부에는 WidgetBuilder가 오는데 이건
Widget Function(BuildContext context) 타입을 typedef한 파생 타입입니다.
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
}
onPressed: () {
Navigator.pop(context);
}
미리 route를 정의해놓고, Navigator.pushNamed() 함수를 이용합니다.
route를 정의할 때는 MaterialApp 위젯의 initialRoute와 routes 속성을 이용합니다.
route는 Map 타입 입니다.
Navigator.pushNamed() 함수에서는 context와 route 속성에 사용했던 키 문자열을 매개변수로 사용합니다.
initialRoute를 사용하거나 Routes에 "/" named route를 정의한 경우에는 home 속성을 정의하면 안됩니다.
MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => FirstScreen(),
'/second': (context) => SecondScreen(),
},
);
onPressed: () {
Navigator.pushNamed(context, '/second');
}
화면을 정의하는 위젯 내부에 받을 데이터 속성을 정의하고 생성자를 이용해서 넘김.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class Todo {
final String title;
final String description;
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 {
final List<Todo> todos;
TodosScreen({Key key, @required this.todos}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Todos'),
),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
);
}
}
class DetailScreen extends StatelessWidget {
final Todo todo;
DetailScreen({Key key, @required this.todo}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(todo.title),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Text(todo.description),
),
);
}
}