프로그래밍/플러터

TabBarView & BottomNavigation

스루나루 2024. 3. 4. 21:45
728x90
728x90

 

서론

 해당 부분은 휴대폰의 센서 및 탭바와 네비게이션 연동을 다룬다. 

 또한 상태변화에 대해 사용을 하는데 상단에서 하위 위젯의 파라미터를 넘길 때 파라미터 및 함수를 넘겨주면 하위 위젯이 해당 함수나 파라미터 값을 변경하여 상위 위젯의 상태변화를 일으킬 수 있다. 

 

 

본문 

 

출처 : https://www.lgcns.com/blog/it-trend/19957/

 

1. Sensor_Plus 

 

 1) 가속도계 

  - 물체가 특정 방향으로 이동하는 가속도를 측정 : 휴대폰에 이미 내장되어 있음 

 

  2) 자이로스코프 

  - x,y,z축의 회전을 측정 

 

 

2. SVG 이미지 

 - 이미지 파일중에 svg 확장자를 가지고 있는 경우 별도의 라이브러리가 필요 

https://pub.dev/packages/flutter_svg

 

flutter_svg | Flutter package

An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files.

pub.dev

	Center(
          child: SvgPicture.asset('asset/img/dice$number.svg',
          width: 200,
          height: 200,),
        ),

 

 

 3. 상수 

 - 여러 파일에서 사용하는 데이터의 경우 따로 파일을 만들어서 관리하자 

 - const 폴더에 colors.dart를 만들어 색을 관리 

final backgroundColor = Colors.orange[100];
const primaryColor = Colors.black;
// 600키 값을 사용하려면 런타임에서 색상이 계산되니까 const 불가
final secondaryColor = Colors.grey[600];

 

 

 4. Theme 

 - TextStyle도 설정 가능하지만 그 외 슬라이더나 바텀 네비게이션 또 배경색도 여기서 지정 가능 

void main() {
  runApp(MaterialApp(
    theme: ThemeData(
      // 배경색
      scaffoldBackgroundColor: backgroundColor,
      // 슬라이더 테마 
      sliderTheme: SliderThemeData(
        thumbColor: primaryColor,
        activeTrackColor: primaryColor, // 활성화 
        inactiveTrackColor: primaryColor.withOpacity(0.3), // 비활성화 
      ),
      bottomNavigationBarTheme: BottomNavigationBarThemeData(
        selectedItemColor: primaryColor, // 선택 
        unselectedItemColor: secondaryColor, // 비선택
        backgroundColor: backgroundColor,
      )
    ),
    home: RootScreen(),
  ));
}

 

 

 5. TabBarView 

 - 텝 인터페이스 구현할 때 사용 

 - 여러 탭 간 위젯을 스와이프하여 전환 가능 

 - 이 위젯 또한 TabController를 가지고 해당 컨트롤러를 통해서 탭에 동작이 있을 때마다 감지하고 제어 controller매개변수 사용 

 - 아래 코드에서도 TabController를 가지고 TabBarView를 제어하며 initState()로 초기화 및 리스너 등록 dispose()에서 리스너 삭제를 함 

 - TickerProviderStateMixin에서 얻은 Ticker를 vsync의 매개변수 this로 넘김 

 - vsync는 애니메이션 속도를 화면의 재생빈도와 동괴화 하는데 사용 즉 더 부드럽고 최적화된 애니메이션 제공 

 

// TickerProviderStateMixin : TabController 초기화를 하려면 vsync기능이 필요한데 TickerProviderStateMixin 요거 넣어야 할 수 있음
class _RootScreenState extends State<RootScreen> with TickerProviderStateMixin {
  
  TabController? controller;

  @override
  void initState() {

    super.initState();
    // 컨트롤러 초기화  vsync 때문에 TickerProviderStateMixin 이거 씀
    controller = TabController(length: 2, vsync: this);

    // 탭 버튼 누르는 등 변경사항이 있으면 addLisnter를 호출
    controller!.addListener(tabListener);

  }

  // 탭 컨트롤러의 속성 변경시 콜백되는 함수
  tabListener() {
    setState(() {});
  }

  @override
  void dispose() {
    controller!.removeListener(tabListener);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: TabBarView(
        controller: controller,
        children: renderChildren(),
      ),
    );
  }

 

TickerProviderStateMixin 사용 이유

- TabBarView 내부에서 발생하는 애니메이션을 위한 Ticker를 쓰기 위해서 사용 탭 간 전환을 할 때 애니메이션이 사용되는데 이 애니메이션이 Ticker를 필요로 함 
- Ticker는 매 프레임마다 콜백 호출하는 내부 매커니즘으로 애니메이션 프레임 생성 
- TickerProviderStateMixin 요고 거지고 오지면 State 클래스에 TickerProvider 기능 추가해서 State객체가 TIcker생성을 할 수 있게 만들고 이를 통해 탭바의 애니메이션에 도움을 준다 


 

 

 6. BottomNavigation 

 - 하단 탭 인터페이스를 구현하는 위젯 

 - 현재는 TabBarView랑 같이 써서 네비게이션 이동할 때 혹은 탭바가 스와이프할 때 서로서로 연동을 시켜서 사용 

 - 탭바에 있는 컨트롤러를 가지고와서 탭바의 변화를 인덱스로 가지고 온 다음 네비게이션 동작할 때 컨트롤러로 탭바뷰도 변경시킴 

BottomNavigationBar renderBottomNavigation() {
    // 탭 네비게이션 바텀 위젯
    return BottomNavigationBar(
        currentIndex: controller!.index,
        onTap: (int index) {
          setState(() {
            controller!.animateTo(index);
          });
        },
        items: [
          BottomNavigationBarItem(
              icon: Icon(
                Icons.edgesensor_high_outlined,
              ),
              label: '주사위'),
          BottomNavigationBarItem(
              icon: Icon(
                Icons.settings,
              ),
              label: '설정'),
        ]);
  }

 

 

 7. Slider 

 - 드래그로 값을 변경할 수 있는 위젯 

 - 최솟값과 최댓값을 설정하여 유저가 값을 설정할 수 있게 하고 해당 값을 연동해서 root_screen에서 파라미터로 넘겨준 값을 변경하여 주사위 민감도를 변경 

 

class SettingScreen extends StatelessWidget {
  // 슬라이더의 현재값
  final double threshold;

  // 슬라이더 변경될 때마다 실행되는 함수
  final ValueChanged<double> onThresholdChange;

  const SettingScreen(
      {super.key, required this.threshold, required this.onThresholdChange});

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Slider(
          // 슬라이더 최솟값
          min: 0.1,
          // 슬라이더 최댓값
          max: 10.0,
          // 최솟값과 최댓값 사이 구간 갯수
          divisions: 101,
          // 슬라이더 선택값
          value: threshold,
          // 슬라이더 조작시 실행되는 함수
          onChanged: onThresholdChange,
          // 슬라이더 표시 값
          label: threshold.toStringAsFixed(1),
        ),
      ],
    );
  }
}

 

 

 

참고

 

《Must Have 코드팩토리의 플러터 프로그래밍 2판》의 스터디 내용 입니다.

728x90
728x90