❮
[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),
      ),
    );
  }
}
