flutter.dev

네임드 라우트에 인자 전달하기

paulaner80 2019. 4. 26. 10:42
반응형



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