플러터:화면 전환(화면 쌓기, 하단 네비게이션 바)(화면 쌓기, 하단 네비게이션 바)
(플러터:화면 전환(화면 쌓기, 하단 네비게이션 바)에서 넘어옴)
개요[편집 | 원본 편집]
네이게이션을 통한 화면전환.
기본적으로 네비게이션바로 구조를 잡고, 네비게이터로 상세 화면을 다루는 형식을 많이 쓴다.
[편집 | 원본 편집]
- Flutter 앱에서 화면을 이동하는 가장 기본적인 방식은 Navigator를 사용하는 것이다.
- Navigator는 “화면(stack)”을 관리하며, 새로운 페이지를 push하여 화면을 열고 pop하여 닫는다.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Navigator Demo',
debugShowCheckedModeBanner: false,
home: FirstPage(),
);
}
}
class FirstPage extends StatelessWidget {
// StatelessWidget: 상태(state)를 가지지 않는 화면
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("첫 번째 화면"),
),
body: Center(
child: ElevatedButton(
child: Text("두 번째 화면으로 이동"),
onPressed: () {
// 화면 이동 (push)
Navigator.push(
context,
MaterialPageRoute(builder: (_) => SecondPage()),
);
},
),
),
);
}
}
class SecondPage extends StatelessWidget {
// 두 번째 화면도 상태를 가지지 않는 StatelessWidget
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("두 번째 화면"),
),
body: Center(
child: Text(
"여기는 두 번째 화면!",
style: TextStyle(fontSize: 24),
),
),
);
}
}
이해를 위한 추가 설명[편집 | 원본 편집]
| 요소 | 설명 | 비고 |
|---|---|---|
| 화면을 위에 올리기.
Navigator.push |
Navigator.push(
context,
MaterialPageRoute(builder: (_) => SecondPage()),
);
새로운 페이지를 스택 위에 ‘올려서’ 이동한다. MaterialPageRoute는 기본적인 화면 전환 애니메이션을 제공한다. |
마테리얼 디자인 규칙에 따라 뒤로가기가 가능하면 자동으로 뒤로가기 버튼이 생긴다. |
| 뒤로 가기
Navigator.pop |
Navigator.pop(context)
현재 페이지를 스택에서 제거(pop)하여 이전 화면으로 돌아간다. |
결론[편집 | 원본 편집]
스택을 쌓아 화면이 바뀐다.
의문[편집 | 원본 편집]
왜 push()는 context가 필요한가?[편집 | 원본 편집]
Navigator는 위젯 트리 안에 존재하는 “Navigator State”를 찾아야 하는데, 이를 위해 현재 위젯의 BuildContext가 필요하다.
BuildContext는 “현재 위젯이 트리에서 어디 위치하는지”를 나타내는 정보다.
MaterialPageRoute 말고 다른 것도 있나?[편집 | 원본 편집]
있다.
- CupertinoPageRoute (iOS 스타일 전환)
- PageRouteBuilder (전환 애니메이션 직접 커스텀)
- go_router, auto_route 같은 라우팅 라이브러리
기본 예제는 MaterialPageRoute로 충분하다.
기본 하단 네비게이션 바[편집 | 원본 편집]
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'BottomNavigation Demo',
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _selectedIndex = 0; // 현재 선택된 탭
// 탭마다 보여줄 화면
static const List<Widget> _pages = <Widget>[
Center(
child: Text(
'첫 번째 화면',
style: TextStyle(fontSize: 24),
),
),
Center(
child: Text(
'두 번째 화면',
style: TextStyle(fontSize: 24),
),
),
Center(
child: Text(
'세 번째 화면',
style: TextStyle(fontSize: 24),
),
),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index; // 탭 선택 시 상태 변경
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('BottomNavigationBar Demo'),
),
body: _pages[_selectedIndex], // 현재 선택된 화면 표시
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
onTap: _onItemTapped, // 탭 클릭 시 호출
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: '홈',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: '비즈니스',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: '학교',
),
],
),
);
}
}
이해를 위한 추가 설명[편집 | 원본 편집]
| 요소 | 설명 | 비고 |
|---|---|---|
| _onItemTapped | 탭 클릭 시 호출되는 함수.
자동으로 Index가 입력된다. |
|
| BottomNavigationBarType | 옵션은?
기본값은 탭이 3개 이상이면 fixed, 3개 이하이면 shifting 기본값은 아래 옵션으로 바꾸어 지정 가능. type: BottomNavigationBarType.fixed, // 고정형 |
shifting이면 각 탭에 색을 넣어주어야 한다.
backgroundColor: Colors.blue, 형태로. |
의문[편집 | 원본 편집]
StatelessWidget으로도 만들 수 없나?[편집 | 원본 편집]
탭 선택 상태를 저장할 방법이 없으므로 일반 StatelessWidget으로는 불가능하다. 탭 상태를 유지하면서 화면 전환하려면 StatefulWidget을 사용해야 한다.