화면 구성에 사용되는 다양한 class에 대한 설명이 아래의 URL에 있다.
https://api.flutter.dev/flutter/material/MaterialApp-class.html
MaterialApp
MaterialApp은 Material Design을 사용하는 애플리케이션이다.
예시에 자주 나오는 중요 클래스
상속 관계 : Object > DiagnosticableTree > Widget > StatefulWidget > MaterialApp
(MaterialApp : Null safety)
[Property]
1. title : App에 대한 AppBar 와는 다르게 이름 붙여주는 Property
[Cautions]
1. Red Text와 Yellow Line이 있는 경우 -> Text에 Material Ancestor가 없는 경우에 발생하는 에러
2. MaterialApp > home > Scaffold > body > Center > child > Text
(Scaffold에는 body가 있고, Center에는 Child가 있다.)
3. 만약에 Route로 home 경로를 지정해두었으면, MaterialApp의 home 속성에는 아무것도 없어야 함.
home (Property) : MaterialApp의 가장 큰 화면을 차지한다는 의미가 아닌 경로 root에 있는 Widget을 지정해주는 역할
"The Widget for the default route of the app (Navigator.defaultRouteName, which is /)"
// Route를 지정하는 방법
// routes: <String, WidgetBuilder>
MaterialApp(
routes: <String, WidgetBuilder>{
'/': (BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home Route'),
),
);
},
'/about': (BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('About Route),
Navigator
app의 Page Stack을 관리하는 클래스 (Route Stack)
Stack Discipline으로 Child Widget을 관리하는 Widget
모바일 앱들은 screen이나 Page라는 이름으로 컨텐츠를 보여주는데, flutter에서는 이를 route라고 함.
그리고, route 스택을 navigator가 관리함.
2가지 방식으로 활용함
1) Declarative : API Navigator.pages
2) Imperative : API Navigator.push, Navigator.pop
System UI로 back button을 제공하지 않는 경우에는 AppBar를 사용하여 back으로 갈 수 있다.
> Navigator.pages
Navigator에 의하여, Navigator.pages는 a stack of Routes로 변경됨
Navigator.pages가 변경되면 그로 인해 stack of Routes가 업데이트 된다.
즉, Navigator는 routes를 Navigator.pages와 동일하게 맞추기 위해 지속적으로 업데이트 한다.
> Navigator.onPopPage
pop되는 경우에 input page를 어떻게 clean up 할지에 대한 callback 함수
> DefaultTransitionDelegate
screen의 변경 방식을 결정하는 클래스.
Custom하기 위해서, TransitionDelegate subclass를 정의하고, Navigator.transitionDelegate에 대입하면 됨.
> Navigator.push
: stack에 새로운 route를 push하기 위해서는 builder가 포함된 MaterialPageRoute의 instacne를 만들어서 Navigator push 하면 됨.
Navigator.push (context, MaterialPageRoute<void>(
builder: (BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('My Page')),
body: Center(
child: TextButton(
child: Text('Pop'),
onPressed: () {
Navigator.pop(context);
> Mobile app은 종종 다량의 route를 관리하기 때문에 이름으로 부르는 것이 쉬움
이렇게, route를 만들어 낼 수 있음.
runApp(MaterialApp(
home: MyAppHome(),
routes: <String, WidgetBuilder> {
'/a': (BuildContext context) => MyPage(title: 'page A'),
'/b': (BuildContext context) => MyPage(title: 'page B'),
'/c': (BuildContext context) => MyPage(title: 'page C'),
Context
Context 클래스는 종료 시점의 변수들을 저장하는 데이터 구조
Object > Response > Obj > Context
BuildContext
https://api.flutter.dev/flutter/widgets/BuildContext-class.html
Scaffold
AppBar나 Drawer와 같은 표준 app element를 제공.
AppBar : AppBar는 user가 Website나 Platform을 돌아다닐 때 도움을 주는 Navigator 역할
(AppBar 가이드라인 : https://balsamiq.com/learn/ui-control-guidelines/app-bars/)
Drawer (= Modal navigation Drawer) : 기존 Screen Layout에 영향을 주지 않고, 배경에 scrim을 친 후 좌측에서 다양한 옵션을 제공하는 app element
AppBar
- PreferredSizeWidget 클래스를 구현한 인터페이스만 AppBar에 올 수 있음.
(https://api.flutter.dev/flutter/widgets/PreferredSizeWidget-class.html)
Route
Flutter 에서 Page 와 Screen은 Route로 불림 (Activity(안드로이드) = ViewController(ios))
(다른 방법도 있지만) 서로 다른 Route 사이를 navigate 할 때 Navigator를 사용할 수 있음
<예시 1번 : Navigator.pop() 을 통해서 이전 페이지로 이동하는 방법>
1. Route 2개 생성
2. Navigator.push()를 통해서 2번째 Route로 이동
-> MaterialPageRoute를 활용하는게 좋음 (왜냐하면, Platform 특정의 애니매이션을 활용하기 때문)
3. Navigator.pop()을 통해서 1번째 Route로 리턴
-> 이후에는 그냥 Navigator.pop()을 동작해서 끝내기.
https://docs.flutter.dev/cookbook/navigation/navigation-basics
child: ElevatedButton(
child: const Text('Open route'),
onPressed: () {
Navigator.push (
context,
MaterialPageRoute(builder: (context) => const SecondRoute()),
);
},
),
child: ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Go Back!'),
)
<예시 2번 : Route name을 이용해서 페이지 이동하는 방법>
named route를 정의하고, navigation에 named route를 사용해야 함. 이때, Named Route는 Navigator.pushNamed()를 사용하고, Route를 정의할 때는 MaterialApp의 Routes 에서 <String, WidgetBuilder>를 사용해서 context를 넘겨줘서 빌드
runApp(MaterialApp(
title: 'Navigation Basics',
initialRoute: '/',
routes: <String, WidgetBuilder>{
'/': (context) => const FirstRoute(),
'/second': (context) => const SecondRoute(),
},
));
1. Create two screens
2. Define the routes
-> (button의 child에서 Navigator를 직접 호출 X) 대신 MaterialApp에서 InitialRoute나 routes에 대해서 선언 필요
3. Navigate to the second screen using Navigator.pushNamed(context, arguments)
4. Navigate to the first screen using Navigator.pop()
< - 매우 중요 - 예시 3번 : Route에 argument 넘겨주기>
ModalRoute.of( )에서 argument를 꺼내오거나, onGenerateRoute( ) function을 활용해서, 파라미터를 넘길 수 있음
1. 넘길 argument 정의
ScreenArguments
2. argument를 뽑아낼 widget 정의
-> ModalRoute.of(context).settigns.arguments as { } 에서 argument를 뽑아내고, 1번에서 정의한 클래스에 cast 함
final args = ModalRoute.of(context)!.settings.arguments as ScreenArguments;
3. routes 테이블에 widget 등록
4. Navigating Widget
- ModalRoute.of( ) : argument와 함께, 현재 Route를 return 해줌
@override
Widget build(BuildContext context) {
// Extract the arguments from the current ModalRoute
// settings and cast them as ScreenArguments.
final args = ModalRoute.of(context)!.settings.arguments as ScreenArguments;
return Scaffold(
appBar: AppBar(
title: Text(args.title),
),
body: Center(
child: Text(args.message),
),
);
https://docs.flutter.dev/cookbook/navigation/navigate-with-arguments
또는 아래와 같이 onGenerateRoute( ) function을 통해서 widget에 전달할 수 있음
이 경우에는 버튼을 누를 때, Settings에 설정을 부여해서, 그에 맞는 route를 연결하도록 설정한 것임.
MaterialApp(
onGenerateRoute: (settings) {
if (settings.name == PassArgumentsScreen.routeName) {
final args = settings.arguments as ScreenArguments;
return MaterialPageRoute(
builder: (context) {
return PassArgumentsScreen(
title: args.title,
message: args.message,
);
},
);
}
assert(false, 'Need to implement ${settings.name}');
return null;
},
)
<예시 4번 : Return Data from a screen>
Button
TextButton ( <- FlatButton)
ElevatedButton ( <- RaisedButton)
OutlinedButton ( <- OutlineButton)
[속성]
Child, onPressed
[특징]
Child가 정의되어 있지 않을시 에러 발생
FutureBuilder
'Application > Flutter' 카테고리의 다른 글
[Cookbook] Internet에서 데이터 가져오기 (0) | 2022.08.03 |
---|---|
[Widget] TabBar, TabBarView (0) | 2022.07.26 |
[Cookbook] Background에서 JSON parsing 하는 방법 (0) | 2022.07.25 |
[Cookbook] Authenticated Request 보내는 방법 (0) | 2022.07.25 |
[Cookbook] Networking - 데이터 삭제 (0) | 2022.07.20 |