앱을 사용하다보면 다른 화면으로 전환하고 이전 화면으로 돌아가는 등의 액션을 하게된다.
1. 다른 화면으로 이동하는 방법
사전작업 : MainPage, SubPage 2가지 화면
- Navigator 클래스의 push() 메소드 이용 : 첫번째 인수 context, 두번째 인수 MaterialPageRoute 필요(머터리얼 디자인 화면간 전환)
- builder 프로퍼티에 이동할 페이지 나타내줌
- push() 메소드를 이용하면 메모리에 기존 화면이 계속 남아 있으므로, SubPage에서는 push()가 아닌 pop()메소드를 이용하자.
* pop() : 현재 화면을 종료하고 이전 화면으로 돌아간다.
// 메인 페이지
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Main Page')
),
body: RaisedButton(
color: Colors.green,
child: Text('Sub Page로 이동'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SubPage())
);
},
)
);
}
}
// 서브 페이지
class SubPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Sub Page')
),
body: RaisedButton(
color: Colors.deepOrange,
child: Text('Main Page로 이동'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MainPage())
);
},
)
);
}
}
- MainPage -> SubPage에 값 전달하기
SubPage에 값을 전달하려면 아래처럼 MainPage에서 파라미터를 넘기고 SubPage 생성자에서 셋팅해주자
* MainPage 버튼클릭시 파라미터 넘기기 : SubPage(myCar: myCar)
* SubPage 생성자에서 셋팅해주자 : SubPage({@required this.myCar});
class Car {
String brand;
String color;
int price;
Car(this.brand, this.color, this.price);
}
...
// 메인 페이지
class MainPage extends StatelessWidget {
...
onPressed: () {
final myCar = Car('RENAULT SAMSUNG', 'WHITE', 3000);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SubPage(myCar: myCar))
);
},
)
);
}
}
// 서브 페이지
class SubPage extends StatelessWidget {
final Car myCar;
SubPage({@required this.myCar});
@override
Widget build(BuildContext context) {
...
}
- 이전 화면으로 값 돌려주기
원리 : 최초 MainPage에서 onPress할 때 async와 await 키워드를 넣어주고 SubPage로부터 받은 데이터를 리턴받는다.
// 메인 페이지
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
...
onPressed: () async { // async 키워드를 추가
final myCar = Car('RENAULT SAMSUNG', 'WHITE', 3000);
final receive = await Navigator.push( // await 키워드 추가, 리턴값 받기
context,
MaterialPageRoute(builder: (context) => SubPage(myCar: myCar))
);
print(receive.toString());
},
)
);
}
}
// 서브 페이지
class SubPage extends StatelessWidget {
...
Navigator.pop(context, 'returnData'); // pop시 돌려줄 데이터 추가
...
}
ex) MainPage > SubPage > MainPage 돌아오며 가져온 데이터 MainPage에서 보여주기
1. 'Sub Page로 이동' 클릭해서 화면 이동
- async ~ await 키워드를 통해 넘어오는 값을 기다리게 된다. (넘어오는 값은 (Future) receive에 담을 예정)
2. 'Main Page로 이동' 클릭해서 화면 이동
- 'data From SubPage' 문자열을 화면 이동시 함께 넘겨준다.
3. 위 문자열을 receive로 받고 setState()로 returnMessage값을 변경해준다.
4. returnMessage값이 MainPage에 나타난다.
// 메인페이지
class MainPage extends StatefulWidget {
@override
_MainPageState createState() => _MainPageState();
}
class _MainPageState extends State<MainPage> {
var returnMessage = "";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Main Page')
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
RaisedButton(
color: Colors.green,
child: Text('Sub Page로 이동'),
onPressed: () async { // async 키워드를 추가
final myCar = Car('RENAULT SAMSUNG', 'WHITE', 3000);
final receive = await Navigator.push( // await 키워드 추가, 리턴값 받기
context,
MaterialPageRoute(builder: (context) => SubPage(myCar: myCar))
);
setState(() {
returnMessage = receive;
});
},
),
Text(returnMessage)
],
),
),
);
}
}
// 서브 페이지
class SubPage extends StatelessWidget {
final Car myCar;
SubPage({@required this.myCar});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Sub Page')
),
body: Center(
child: RaisedButton(
color: Colors.deepOrange,
child: Text('Main Page로 이동'),
onPressed: () {
Navigator.pop(context, 'data From SubPage'); // pop시 돌려줄 데이터 추가
},
),
)
);
}
}
2. routes를 활용한 내비게이션
위 방법으로는 페이지를 이동할 때 해당 페이지명을 작성해주었다. routes를 활용한 내비게이션을 이용하면 좀더 간결하게 구성 가능하다.
- routes는 MaterialApp에서 정의할 수 있다.
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MainPage(),
routes: {
'/main': (context) => MainPage(),
'/sub': (context) => SubPage(),
},
);
}
}
- routes 프로퍼티를 추가한 후에 아래 코드에서 소스를 2군데만 고치면 된다.
final receive = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => SubPage(myCar: myCar))
);
* Navigator.push -> Navigator.pushNamed (routes로 정한 예명 페이지를 호출)
* MaterialPageRoute(~~~ 해당 페이지) -> routes명 (표현이 간결해짐)
final receive = await Navigator.pushNamed(context, '/sub');
댓글