Develop/Flutter

[Flutter] 커스터마이징 네비게이션 바 convex_bottom_bar 쉽게 사용해보기

issuemaker99 2024. 9. 28. 23:29
728x90

convex_bottom_bar는 Flutter에서 사용 가능한 커스터마이징 가능한 하단 네비게이션 바 패키지입니다. 일반적인 하단 네비게이션 바에 독특한 애니메이션 효과와 함께 중간에 튀어나오는 버튼이 추가된 디자인을 제공합니다. 이 패키지는 특히 사용자 경험을 향상시키고, UI에 좀 더 활기를 불어넣는 데에 적합합니다.

 

convex_bottom_bar

https://pub.dev/packages/convex_bottom_bar

 

convex_bottom_bar | Flutter package

A Flutter package which implements a ConvexAppBar to show a convex tab in the bottom bar. Theming supported.

pub.dev

 

패키지 설치

pubspec.yaml 파일에 convex_bottom_bar 패키지를 추가해 설치할 수 있습니다.

flutter pub get

 

기본 사용법

convex_bottom_bar를 사용하기 위해서는 Flutter 프로젝트에서 하단 네비게이션을 적용할 Scaffold 위젯의 bottomNavigationBar 속성에 설정하면 됩니다. 기본적으로 5개의 탭 아이템을 설정할 수 있으며, 중간의 탭이 튀어나와 있는 형태로 나타납니다.

기본 심플 예제소스)

import 'package:flutter/material.dart';
import 'package:convex_bottom_bar/convex_bottom_bar.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _selectedPage = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Convex Bottom Bar Example'),
      ),
      body: Center(
        child: Text('Page $_selectedPage'),
      ),
      bottomNavigationBar: ConvexAppBar(
        items: [
          TabItem(icon: Icons.home, title: 'Home'),
          TabItem(icon: Icons.map, title: 'Discovery'),
          TabItem(icon: Icons.add, title: 'Add'),
          TabItem(icon: Icons.message, title: 'Messages'),
          TabItem(icon: Icons.people, title: 'Profile'),
        ],
        initialActiveIndex: 0,
        onTap: (int i) {
          setState(() {
            _selectedPage = i;
          });
        },
      ),
    );
  }
}

위 코드는 5개의 탭 아이템이 있는 간단한 하단 네비게이션 바 예제입니다. 아이템을 클릭할 때마다 화면에 해당하는 페이지 번호가 표시됩니다.

주요 속성

  • items: 탭에 표시될 아이템 목록을 설정합니다. TabItem 클래스는 icon과 title을 받아서 각각의 탭을 구성합니다.
  • initialActiveIndex: 기본으로 활성화된 탭을 설정합니다.
  • onTap: 탭이 클릭될 때 호출되는 콜백 함수입니다.

스타일 커스터마이징

convex_bottom_bar는 기본 스타일 외에도 다양한 스타일 옵션을 제공합니다. 예를 들어, style 속성을 사용하여 하단 바의 스타일을 변경할 수 있습니다.

ConvexAppBar(
  style: TabStyle.react,  // 다양한 스타일 옵션 사용 가능 (fixed, flip, textIn, etc.)
  items: [
    TabItem(icon: Icons.home, title: 'Home'),
    TabItem(icon: Icons.map, title: 'Discovery'),
    // ...
  ],
)

 

TabStyle 옵션에는 다음과 같은 스타일이 있습니다:

  • fixed: 일반적인 하단 네비게이션 바 스타일.
  • react: 선택한 탭이 반응형 애니메이션을 제공.
  • flip: 선택한 탭이 뒤집어지는 애니메이션.

커스텀 컬러 적용

다음과 같이 색상을 커스터마이징하여 앱 테마에 맞는 색감을 적용할 수 있습니다.

ConvexAppBar(
  backgroundColor: Colors.blue,  // 바 배경색
  activeColor: Colors.white,     // 활성화된 아이콘 색상
  color: Colors.grey,            // 비활성화된 아이콘 색상
  items: [
    TabItem(icon: Icons.home, title: 'Home'),
    TabItem(icon: Icons.map, title: 'Discovery'),
    // ...
  ],
)

 

고급 기능

1. Floating 버튼 커스터마이징

중앙에 위치한 플로팅 액션 버튼을 커스터마이징할 수 있습니다.

ConvexAppBar(
  items: [
    TabItem(icon: Icons.home, title: 'Home'),
    TabItem(icon: Icons.map, title: 'Discovery'),
    TabItem(icon: Icons.add, title: ''),  // 플로팅 버튼
    TabItem(icon: Icons.message, title: 'Messages'),
    TabItem(icon: Icons.people, title: 'Profile'),
  ],
  backgroundColor: Colors.deepPurple,
)

 

2. 다이나믹한 네비게이션 아이템 변경

상태에 따라 네비게이션 아이템을 다이나믹하게 변경할 수 있습니다.

setState(() {
  items = [
    TabItem(icon: Icons.home, title: 'Home'),
    TabItem(icon: Icons.map, title: 'New Item'),
  ];
});


TabStyle 을 fixed 로 해서 만든 아주 간단 예제 소스 입니다.

 

1. 폴더 및 파일

2. data.dart

import 'package:convex_bottom_bar/convex_bottom_bar.dart';
import 'package:flutter/material.dart';

class Data {
  static List<TabItem> items() {
    return [
      const TabItem<IconData>(icon: Icons.home, title: 'Home'),
      const TabItem<IconData>(icon: Icons.map, title: "Discovery"),
      const TabItem<IconData>(icon: Icons.publish, title: "Publish"),
      const TabItem<IconData>(icon: Icons.message, title: 'Message'),
      const TabItem<IconData>(icon: Icons.people, title: 'Profile'),
    ];
  }
}

 

3. main.dart

import 'package:convex_bottom_bar/convex_bottom_bar.dart';
import 'package:flutter/material.dart';
import 'package:wise_bowel_movements/model/data.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  final List<TabItem> _tabItems = Data.items();

  TabController? _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: _tabItems.length, vsync: this);
  }

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('ConvexAppBar'),
          backgroundColor: const Color(0xFF3F51B5),
        ),
        body: TabBarView(
            controller: _tabController,
            children: _tabItems
                .map(
                  (i) => Center(
                    child: Text(
                      '${i.title} World',
                      style: const TextStyle(fontSize: 30),
                    ),
                  ),
                )
                .toList(growable: false)),
        bottomNavigationBar: ConvexAppBar(
          items: _tabItems,
          style: TabStyle.fixedCircle,
          curve: Curves.bounceInOut,
          shadowColor: const Color(0xFF3F51B5),
          backgroundColor: const Color(0xFF3F51B5),
          controller: _tabController,
          onTap: (int i) => debugPrint('select index=$i'),
        ),
      ),
    );
  }
}
LIST