Navigatoer는 식별자를 사용해서 네임드 라우트로 화면이동할 수 있도록 해줍니다. 그런데 네임드 라우트에 인자들을 넘겨주고 싶은 경우도 있습니다.
예를 들어 /user 라우트로 화면을 이동때 user의 정보를 같이 넘겨 주는 경우 입니다.
Navigator.pushNamed 메소드에 인자들을 추가해서 넘겨주면 사용하면 이런 작업을 할 수 있습니다
@optionalTypeArgs
Future<T> pushNamed <T extends Object>(
BuildContext context,
String routeName, {
Object arguments
})
ModalRoute.of 메소드 혹은 MaterialApp 이나 CupertinoApp 생성자의 onGenerateRoute 함수를 사용해 인자들을 꺼내 올 수 있습니다.
이 예제에서는 네임드 라우트에 인자값을 전달하는방법 과 ModelRoute.of 와 onGenerateRoute를 사용해 인자를 꺼내오는 방법을 설명하겠습니다.
디렉션
1. 넘겨줄 인자값 정의
2. 넘겨받을 위젯 생성
3. 그 위젯을 routes 테이블에 등록
4. 그 위젯으로 화면이동
1. 넘겨줄 인자값 정의
먼저 새로운 라우트에 넘겨줄 인자들을 정의합니다. 이 예제에서는 두가지 데이터(타이틀과 메시지)를 넘기겠습니다.
두 가지 데이터를 넘기기위해 이 것들을 담을 클래스를 생성합니다.
class ScreenArgument{
final String title;
final String message;
ScreenArgument(this.title, this.message);
}
2. 인자를 받을 위젯 생성하기
넘겨받은 ScreenArgurment 객체로부터 title과 message를 화면에 표시하기 위한 위젯을 만들어야합니다.
ScreenArgurment 객체에 접근하기 위해서는 ModalRoute.of 메소드를 사용합니다. 이 메소드는 인자를 가지고 있는 route를 반환합니다.
class ExtractArgumentsScreen extends StatelessWidget{
static const routeName = '/ExtractArguments';
@override
Widget build(BuildContext context) {
final ScreenArgument args = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
title:Text(args.title),
),
body: Center(
child: Text(args.message),),
);
}
}
3. 위젯을 라우트 테이블에 등록하기
엔트리를 MaterialApp을 만들 때 routes 에 추가합니다. routes는 route의 이름을 기반으로 어떤 위젯이 생성될지를 정의합니다.
MaterialApp{
routes : {
ExtractArgumentsScreen.routeName : (context) => ExtractArgumentsScreen(),
}
}
4. 위젯으로 화면전환하기
마지막으로, 사용자가 버튼을 탭했을 때 Navigator.pushNamed를 사용해서 ExtractArgumentsScreen으로 화면전환합니다. arguemnt 속성을 통해서 route에 인자를 전달합니다. ExtractArgumentsScreen에서는 title과 message를 인자에서 꺼냅니다.
RaisedButton(
child : Text("Navigate to screen that extracts arguments"),
onPress : (){
Navigator.pushNamed(
context,
ExtractArgumentsScreen.routeName,
arguments : ScreenArgurments{
"Extract Arguements Screen",
"This message is extracted in th build method."
}
)
}
)
onGenerateRoute 를 사용해서 인자를 추출하기
위젯에서 인자를 직접꺼낸는 것 대신, onGenerateRoute 함수에서 인자들을 꺼내고 전달할 수있습니다.
onGenerateRoute 함수는 지정된 RouteSettings를 기반으로 적절한 경로를 만듭니다.
MaterialApp(
//네임들 라우트를 관리할 수 있는 함수를 제공한다.
//적절한 네임드 라우트를 사용해서 라우트를 푸쉬하려면
//이 함수를 사용해야합니다.
onGenerateRoute(settings){
//만약 PassArgumentsScreen을 푸위하고 싶으면
if(settings.name = PassArguemntScreen.routeName){
//인자를 ScreenArguments 타입으로 캐스트하기
final ScreenArgurments args = settings.arguments;
//arguments로 부터 필요한 인자값을 추출한다.
//그리고 그 데이터를 적절한 스크린으로 전달한다.
return MaterialApp(
build(context){
return PassArguemntScreen(
title : args.title,
message : args.message
)
}
)
}
}
)
[전체소스]
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// Provide a function to handle named routes. Use this function to
// identify the named route being pushed, and create the correct
// Screen.
onGenerateRoute: (settings){
print(settings);
if(settings.name == PassArgumentsScreen.routeName){
final ScreenArgument args = settings.arguments;
return MaterialPageRoute(
builder: (context){
return PassArgumentsScreen(
title: args.title,
message:args.message
);
}
);
}
assert(false, "Need to implement ${settings.name}");
return null;
},
title: 'Flutter Demo',
home: HomeScreen (),
routes : {
ExtractArgumentsScreen.routeName : (context) => ExtractArgumentsScreen()
}
);
}
}
class HomeScreen extends StatelessWidget{
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title:Text("HomeScreen")),
body: Center(
child: Column(children: [
RaisedButton(
child: Text("Navigate to ExtractArgumentsScreen"),
onPressed: (){
Navigator.pushNamed(context, ExtractArgumentsScreen.routeName, arguments: ScreenArgument("title2", "message2"));
},
),
ElevatedButton(
child: Text("Navigate to PassArgumentsScreen"),
onPressed: (){
Navigator.pushNamed(context, PassArgumentsScreen.routeName, arguments: ScreenArgument("title", "message"));
},
)
],),
)
);
}
}
class PassArgumentsScreen extends StatelessWidget{
static const routeName = "/passArguments";
final String title;
final String message;
const PassArgumentsScreen(
{Key key,
@required this.title,
@required this.message})
: super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title:Text(this.title),
),
body: Center(
child: Text(this.message),),
);
}
}
class ExtractArgumentsScreen extends StatelessWidget{
static const routeName = '/ExtractArguments';
@override
Widget build(BuildContext context) {
final ScreenArgument args
= ModalRoute.of(context).
settings.
arguments;
return Scaffold(
appBar: AppBar(
title:Text(args.title),
),
body: Center(
child: Text(args.message),),
);
}
}
class ScreenArgument{
final String title;
final String message;
ScreenArgument(this.title, this.message);
}
https://flutter.dev/docs/cookbook/navigation/navigate-with-arguments
'flutter.dev' 카테고리의 다른 글
리스트 기본 (0) | 2019.05.03 |
---|---|
스크린에 데이터 전달하기 (0) | 2019.05.02 |
데이터 돌려받기 (0) | 2019.04.30 |
네임드 라우트로 화면이동 하기 (0) | 2019.04.25 |
새 화면으로 이동하고 뒤로 돌아오기 (0) | 2019.04.22 |