본문 바로가기
앱 개발 공부

플러터 학습기 (6) - 바텀 내비게이션 바 커스텀하기, theme 설정하기

by polissage 2024. 2. 10.
728x90

상태 관리 쪽 학습을 끝내고 예제를 좀더 학습하려고 하다가 빨리 앱을 만들고 싶은 마음에 앱 개발에 착수했다. 그간 적지 않은 시간이 흘렀고 틈틈히 디자인을 어느정도 해두어, 개발을 시작할 수는 있게 되었다. 험난한 길이 예상되긴 하지만 일단 지금 할 수 있는 것, 해야 할 것 같은 것부터 시작하기로 했다.

 

만들어야 할 페이지가 크게 3개이고, 로그인이나 설정 등은 일단 나중에 생각하기로 했다. 앱바가 있는 상태에서 플로팅 버튼으로 연결되는 화면을 chat gpt로 만들고 나니 바텀 내비게이션바까지 추가하면 기본적인 요소들이 구비되는 것 같아 바텀 내비게이션을 커스터마이징 해보기로 했다. 이와 함께 자주 사용하는 컬러와 폰트를 세팅해놓는 작업도 필요하다는 생각이 들어 테마 설정도 같이 시도해보기로 했다.

바텀 내비게이션 바 추가하기

처음에 코딩셰프님 영상을 보고 다른 파일 안에 내비게이션을 만든 다음 main.dart에 불러오는 방법을 시도하려고 했는데 뭔가 잘되지 않았다. 그리고 항상 필요한 요소는 메인 파일에 있는 것도 나을 것 같아서 몇가지 사례를 찾아보다가 공식문서에 있는 것과 비슷한 형태로 구현했다.

 

https://api.flutter.dev/flutter/material/BottomNavigationBar-class.html

 

BottomNavigationBar class - material library - Dart API

A material widget that's displayed at the bottom of an app for selecting among a small number of views, typically between three and five. There is an updated version of this component, NavigationBar, that's preferred for new applications and applications t

api.flutter.dev

 

class MyPage extends StatefulWidget {
  const MyPage({super.key});

  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  //선택된 인덱스를 첫번째 메뉴로 설정한다.
  int _selectedIndex = 0;

  //각 파일로 구분된 연결 페이지 위젯을 설정한다.
  final List<Widget> _widgetOptions = <Widget>[
    const Habits(),
    const Statistics(),
  ];

  // 탭바 아이콘 클릭시 각 탭에 맞는 인덱스를 불러온다.
  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: SafeArea(
          //선택된 인덱스에 맞는 화면이 선택되게 한다.
          child: _widgetOptions.elementAt(_selectedIndex),
        ),
        bottomNavigationBar: BottomNavigationBar(
            items: <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: SvgPicture.asset(
                  'assets/icons/IconHabits.svg',
                  height: 32,
                  width: 32,
                )
                label: 'Habits',
              ),
              BottomNavigationBarItem(
                icon: SvgPicture.asset(
                  'assets/icons/IconStatistics.svg',
                  height: 32,
                  width: 32,
                ),
                label: 'Statistics',
              ),
            ],
            currentIndex: _selectedIndex,
            onTap: _onItemTapped,
          ),
        ));
  }
}

 

바텀 내비게이션 바 커스텀하기

그 다음에는 디자인에 맞게 바텀 내비게이션바를 커스텀해보았다. 크게 배경색 바꾸기, 상단 보더 넣기, 아이콘 변경하기로 나누어졌다.

 

배경색과 보더는 상대적으로 쉽게 적용할 수 있었다. 바텀 내비게이션 바의 배경색은 MaterialApp 내의 themeData에서 설정할 수 있다.

미리 자주 사용하는 색상을 다른 파일에 정의해두고, 배경색으로 불러왔다.

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ORBIT',
      theme: ThemeData(
        bottomNavigationBarTheme:
           //바텀 내비게이션바 배경색 설정
            const BottomNavigationBarThemeData(backgroundColor: purpleLight2),
        disabledColor: lavenderGreyMedium,
      ),
      home: const MyPage(),
    );
}

 

바텀 내비게이션 바 속성

바텀 내비게이션 바에서 설정할 수 있는 속성 중 눈에 들어오는 것 몇가지를 정리해보자.

바텀 내비게이션 바 상단에 보더 넣기

내비게이션 바 상단에 라인을 넣기 위해 컨테이너를 하나 추가하고 위쪽에만 라인을 넣도록 설정해주었다.

bottomNavigationBar: Container(
   decoration: const BoxDecoration(
      border: Border(
          top: BorderSide(color: purplePrimary2, width: 1.0)),
          ),

 

바텀 내비게이션 바 아이콘 변경하기

직접 만든 아이콘을 넣고 싶어서 처음에는 Flutter Icon Generator 사이트를 사용해보려고 했다. 그러나 피그마에서 export한 svg 아이콘에서 오류가 자꾸 발생해서 svg 아이콘을 직접 업로드하여 사용하기로 했다.

 

asset 파일에 아이콘 파일을 추가해주고, pubspec.yaml 파일에 경로를 추가해준다.

  assets:
    - assets/icons/IconHabits.svg
    - assets/icons/IconStatistics.svg
    - assets/icons/IconPlus.svg

 

중간에 파일명을 변경했더니 잘 불러와지던 아이콘이 안불러와져서 혼났다; 위 파일의 띄어쓰기도 잘 맞추어야 한다..

 

위에 이미 있긴 하지만 디폴트 아이콘 대신 svg 아이콘을 불러오기 위한 코드는 아래와 같다.

BottomNavigationBarItem(
    icon: SvgPicture.asset(
       'assets/icons/IconHabits.svg',
        height: 32,
        width: 32,
        ),

 

아이콘 크기가 좀 커서 사이즈를 조정해주었다.

 

클릭시 바텀 내비게이션 바 아이콘 색상 변경되게 하기

이 때 이미 selected, unselectedItemColor를 지정해두었지만 원하는대로 작동하지 않았다. 조금 찾아보니 activeIcon에 ColorFilter.mode 설정이 필요했다.

BottomNavigationBarItem(
     icon: SvgPicture.asset(
         'assets/icons/IconHabits.svg',
          height: 32,
          width: 32,
         ),
     activeIcon: SvgPicture.asset('assets/icons/IconHabits.svg',
         height: 32,
         width: 32,
         colorFilter:
            const ColorFilter.mode(purplePrimary, BlendMode.srcIn)),
     label: 'Habits',
     ),

 

 

 

여기까지의 결과물!

 

 

 

정리를 하니 간결해보이는데 여기까지 오기까지 많이 헤매었다 ㅠ 그러나 완성해놓고보니 뿌듯했다.

 

폰트와 색상을 포함한 테마 설정을 조금 더 잘해두면 도움이 될 것 같은데, 아직 가장 효율적인 방법을 잘 모르겠다. 이제 다음으로 첫번째 페이지의 레이아웃을 짜고 있는데 이 부분도 이제 공부가 필요해 보인다. 여기까지 개발해보면서 느낀 점은 원하는 특정 결과를 얻기 위한 방법은 다양하다는 것이다. 목적과 상황(어쩌면 실력?)에 맞는 방법을 취사 선택할 수 있어야 하고 더 완성도가 높은 방법을 적용하는 것이 실력인 것 같다.

 

또한 폰트나 색상 커스텀 적용을 많이 해야하는데, 디자인 시스템을 잘 구축해두어야 편할 것 같다.

 

어쨌든 크게 막히기 전까지 쭉쭉 가기로.

 

728x90

댓글