본문 바로가기
Flutter

[Flutter] 플러터 - Riverpod 상태관리 응용, convex_bottom_bar BottomNavigationBar 및 바텀네비 뱃지 구현하기 (1)

by s_hoonee 2024. 3. 5.
반응형

해당 주제의 포스팅은 3편으로 이루어져있습니다. 현재 포스팅은 1편입니다.

필요한 파일은 총 3 + N(바텀 네비 수)개입니다

1. page_index_provider.dart
2. s_main.dart
3. w_convex_bottom.dart 
+ N개 : 저는 5개의 화면을 준비했습니다.
FirstScreen, SecondScreen, ThirdScreen, FourthScreen, FifthScreen

1. Riverpod 상태관리를 위해 상단에 ProviderScope를 달아주고 시작합시다.

 

2. page_index_provider.dart파일에 pageIndexProvider 선언해주기

-> pageIndexProvider는 바텀네비게이션에 사용될 인덱스를 관리합니다.

import 'package:flutter_riverpod/flutter_riverpod.dart';

final pageIndexProvider = StateProvider<int>((ref) => 0);

 

3. 메인 화면에 진입하는 곳 (s_main.dart 파일)에 Scaffold - body에 사용할 화면 리스트 생성후 넣어주기

class MainScreen extends ConsumerStatefulWidget {
  const MainScreen({super.key});

  @override
  ConsumerState<MainScreen> createState() => MainScreenState();
}

class MainScreenState extends ConsumerState<MainScreen> {
 

  @override
  Widget build(BuildContext context) {
    final indexProvider = ref.watch(pageIndexProvider);

    final List<Widget> bodyList = [
      Visibility(visible: indexProvider == 0, child: const FirstScreen()),
      Visibility(visible: indexProvider == 1, child: const SecondScreen()),
      Visibility(visible: indexProvider == 2, child: const ThirdScreen()),
      Visibility(visible: indexProvider == 3, child: const FourthScreen()),
      Visibility(visible: indexProvider == 4, child: const FifthScreen()),
    ];
    return Scaffold(
      body: IndexedStack(
        index: indexProvider,
        children: bodyList,
      ),
      bottomNavigationBar: const ConvexBottomNavigation(),
    );
  }
}

(1) ConsumerStatefulWidget 위젯으로 선언하여 상태관리를 할 수 있게 만들어줍니다.

(2) pageIndexProvider를 감지하도록 indexProvider 변수를 선언합니다.

final indexProvider = ref.watch(pageIndexProvider);

List<Widget> bodyList 변수에 사용할 페이지를  Visibility 위젯과 상태관리로 가져올 indexProvider와 함께 넣어서 초기화하고

상태관리 중인 indexProvider값에 따라 우리가 원하는 페이지로 바뀌게끔 만듭니다.

복잡하게 보일 수 있으나 그냥 상태관리 하는 int값을(pageIndexProvider) 바텀네비를 통해 바꾸어주고 바뀐 값에 따라 Visibility위젯 효과로 사라지고 나타나게하는 눈속임(?) 입니다.

(3) Scaffold의 body에 IndexedStack위젯을 사용합니다.

간단히 IndexedStack위젯의 대해 설명하자면

IndexedStack은 두 가지 주요 속성을 가지고 있습니다:
index: 현재 보여주려는 페이지의 인덱스를 나타냅니다.
children: 보여줄 수 있는 모든 페이지 위젯들을 리스트로 가지고 있습니다.
IndexedStack은 index 속성에 따라 children 리스트에서 해당 인덱스의 위젯만 보여줍니다. 나머지 위젯들은 숨겨집니다.

* IndexedStack속성으로도 바텀네비 구현은 가능하나, Visibility위젯을 추가로 사용하는 이유는 해당 페이지를 가야만 initState가 실행되기 때문입니다. Visibility 없이 그냥 선언해도 기능상 무관하나 이렇게 할 경우 앱을 시작할 때 모든 페이지가 initState가 걸립니다. 리빌드를 어떻게 할지는 프로젝트 특성에 맞게 결정하면 됩니다!!! ( Visibility일 경우 네비를 옮길 때 마다 initState가 실행되는 단점이자 장점도 있음)

IndexedStack 사용의 장점:
1. 여러 화면을 하나의 위젯 계층에서 간편하게 관리할 수 있습니다.
2. 조건부 렌더링: index 속성에 따라 화면을 동적으로 전환할 수 있습니다.
3. 성능 최적화: 현재 보이는 페이지만 렌더링하기 때문에, 모든 페이지를 동시에 렌더링하는 것보다 성능이 좋습니다.


다음 포스팅에서 Scaffold의 속성 bottomNavigationBar을 추가하여 바텀네비를 선택하여 상태관리로 관리중인 indexProvider을 변경, IndexedStack위젯의 기능으로 화면 전환을 구현하는 포스팅을 하겠습니다.

 

2편 바로가기

https://hooninha.tistory.com/99

 

[Flutter] 플러터 - Riverpod 상태관리 응용, convex_bottom_bar 바텀네비게이션 및 바텀네비 뱃지 구현하기

해당 주제의 포스팅은 3편으로 이루어져있습니다. 현재 포스팅은 2편입니다. 필요한 파일은 총 3 + N(바텀 네비 수)개입니다 1. page_index_provider.dart 2. s_main.dart 3. w_convex_bottom.dart + N개 : 저는 5개의

hooninha.tistory.com