Flutter 일기
참고 1 : Flutter.dev - material - BottomNavigationBar class
BottomNavigationBar
이름에서 보이는 그대로, 화면 하단에 Navigation 기능을 하는 영역이다.
휴대폰에서 앱 쓸 때 정말 자주보는 기능이다. 클론 코딩으로 많이 하는 당근마켓이나, 쿠팡 등의 앱을 보자. 화면 하단에 홈 탭이나 검색 탭, 사용자 정보 탭 등이 있으며 해당 탭을 누르면 다른 페이지로 이동한다.
BottomNavigationBar를 쓸 때 required(필수로 넣어야 하는) 속성은 items 하나 뿐이다. List< BottomNavigationBarItem> 형태의 배열을 넣어주면 된다.
대괄호 안에 BottomNavigationBarItem를 여러 개 넣어도 되고, List.generate등의 List builder를 써도 된다. 여기서는 여러 개를 각각 넣는 형태로 쓰겠다. (공식 사이트가 각각 넣었으므로...)
BottomNavigationBar에서는 최소한 탭이 2개 이상이어야 한다. 탭이 몇개인가에 따라 type속성이 변하는데, 3개까지는 fixed, 4개 이상부터는 shifting으로 기능하는 것이 기본이다. type에 대해서는 코드 설명과 함께 알아보자.
코드 예시로 알아보자
오늘은 간만에 공식 사이트의 예제를 가져와서 그대로 돌렸다.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return const MaterialApp(
home: MyStatefulWidget(),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
// 탭을 이동할 때 쓸 변수!
int _selectedIndex = 0;
static const TextStyle optionStyle =
TextStyle(fontSize: 40, fontWeight: FontWeight.bold);
static const List<Widget> _widgetOptions = <Widget>[
Text(
'Index 0: Home',
style: optionStyle,
),
Text(
'Index 1: Business',
style: optionStyle,
),
Text(
'Index 2: School',
style: optionStyle,
),
];
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar Sample'),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
// 아랫줄을 쓰지 않아도 탭이 4개 미만인 경우 기본으로 설정된다.
// type: BottomNavigationBarType.fixed,
// selectedItemColor: Colors.amber[800],
// unselectedItemColor: Colors.blue,
// backgroundColor: Colors.black,
),
);
}
}
맨 아래 주석을 단 3줄은 색상 적용 부분인데, 실행 화면을 보면 바로 이해할 것이다.
주석의 색상 미적용 | 주석 색상 적용 |
---|---|
위에서 알 수 있듯 selectedItemColor 는 탭을 선택했을 때의 색상인데, 설정하지 않으면 ColorScheme.primary 색상(Colors.blue)이 적용된다. backgroundColor도 설정 안하면 흰색(opaque white)!
BottomNavigationBarItem을 하나하나 나열한 형태이며, icon, label 속성은 각각 탭에 보여지는 아이콘과 문구이다.
탭을 이동하려면 currendIndex 속성을 바꿔야 선택한 탭으로 이동한다.
여기서는 _selectedIndex라는 변수를 선언하여 index의 변화를 저장하고, 이 값을 currentIndex에서 쓴다. (탭의 인덱스는 맨 왼쪽부터 0,1,2,3...)
_selectedIndex는 onTap속성에서 변경해준다. 코드 상에서는 함수를 따로 썼던데, 아래와 같이 속성에다 바로 함수를 작성해도 된다.
onTap: (int index) {
setState(() {
_selectedIndex = index;
});
},
위의 코드에서 settings 탭만 추가했다. 실행화면을 바로 보자.
주석의 색상 미적용 | 주석 색상 적용 |
---|---|
색상을 아무것도 적용 안하면 탭이 안보인다. shifting이 적용될 경우 selectedItemColor를 설정하지 않으면 흰색으로 설정되며, backgroundColor또한 흰색이 된다.
색상을 설정하면, 탭한 부분이 살짝 올라오는 것이 보인다. type이 shifting! 움직이기 때문이다. 이게 싫으면 type속성을 fixed로 설정해주면 된다.
backgrounColor는 BarItem별로 따로 설정할 수는 있다. 다만 type이 shifting일 경우에는 BottomNavigationBar수준에서 backgroundColor를 설정했는데 안먹는다;; 첫번째 BarItem에만 backgroundColor를 검정색으로 설정해주었더니 전체 Bar에 적용되는 것을 확인했다 (왜지?)
fixed일때는 BottomNavigationBar수준에서 backgroundColor를 설정하면 잘 적용된다. 이대로 해보면 아래와 같다.
지금은 Text위젯만 띄우는 것으로 했는데, onTap에 Navigator를 쓰면 다른 페이지도 띄울 수 있다!
그리고 bottomNavigationBar에는 BottomNavigationBar 말고도 TabBar라는 것도 쓸 수 있다. 체감상 BottomNavigationBar를 더 많이 쓰는 것 같긴 한데, TabBar 요건 다음에....
오늘의 일기는 여기까지!