목차

  1. 사용된 기능 설명
  2. 사용 예시
    1. 메소드 및 변수 선언
    2. Scaffold 작성
    3. 기타 메소드 작성
    4. 테스트

 

 

✅ 사용된 기능 설명

  • SingleTickerProviderStateMixin : flutter에서 애니메이션을 다룰 때 쓰이는 mixin
    ** 하단에 TabController 사용을 위해 씀
    ** TabController 를 쓰려면 vsync 가 필요한데, 그걸 쓰기 위해 SingleTickerProviderStateMixin (또는 TickerProviderStateMixin) 을 꼭 써야 함
  • mixin : 여러 클래스에서 공통으로 쓰이는 기능(코드)을 재사용하기 위한 도구
  • TabController : 탭(Tab)과 탭에 연결된 화면(View)을 동기화해서 관리하는 컨트롤러
    ** TabBar와 TabBarView 양쪽에 알려주면서 화면 전환을 자연스럽게 연결해주는 역할
    ** 애니메이션을 쓰려면 vsync 라는 게 필요하며, 화면이 보일 때만 애니메이션을 돌려서 성능을 아끼는 장치
    ** vsync 는 TickerProvider 타입이어야 하고, StatefulWidget 의 State 클래스에서 TickerProvider 를 제공해야 함
  • addListener : 객체(TabController, TextEditingController...)의 상태 변화가 일어날 때 실행할 동작을 등록하는 메소드
  • setState() : StatefulWidget에서 상태(State)가 변했음을 Flutter 프레임워크에 알려 UI를 다시 그리게 하는 메소드
    ** StatefullWidget 에서만 사용 가능 
    ** StatelessWidget에선 사용 불가
  • TabBarView : TabController 와 연결되는 페이지 전환 위젯
  • TabBar : TabController 와 연결되는 탭 버튼 담당 위젯
    ** TabBar의 tabs 요소 내의 디폴트는 흰색 글씨라서 변경 필요
  • BuildContext : Flutter 에서 BuildContext 는 위젯이 어디에 위치해 있는지에 대한 메타 정보를 담은 것
  • context : 현재 빌드되는 위치의 BuildContext

 

 

 

✅ 사용 예시

 

1️⃣ 메소드 및 변수 선언

  1. 애니메이션 기능 사용을 위해 Single... 추가
  2. 애니메이션 기능 사용을 위해 TabController 선언
  3. 앱 초기화, 앱 종료 메소드 작성

 

 

2️⃣ Scaffold 작성

  1. 각 아이콘 별 클릭 시, '스르륵'하게 화면 넘어가는 기능을 위해 TabBarView 사용
  2. bottomNavigationBar 작성

 

 

3️⃣ 기타 메소드 작성

  1. body 부분에 사용될 메소드 작성

 

 

4️⃣ 테스트

 

 

 

 

 

 

 

✔️ 사용된 코드

// SingleTickerProviderStateMixin : flutter에서 애니메이션을 다룰 때 쓰이는 mixin
// ** 하단에 TabController 사용을 위해 씀
// ** TabController 를 쓰려면 vsync 가 필요한데, 그걸 쓰기 위해 SingleTickerProviderStateMixin (또는 TickerProviderStateMixin) 을 꼭 써야 함
// mixin : 여러 클래스에서 공통으로 쓰이는 기능(코드)을 재사용하기 위한 도구
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{

  late TabController _tabController;
  int _selectedIndex = 0;   // bottom 아이콘 별 index

  // vsync : 애니메이션의 "프레임 동기화" 담당
  @override
  void initState(){   // 앱 초기화
    super.initState();  // 부모(super) 초기화(initState) 호출
    _tabController = TabController(length: 3, vsync: this); // this : 현재 클래스의 인스턴스. 즉, _MyHomePageState
    _tabController.addListener(
      // setState() : StatefullWidget 에서만 사용 가능 (StatelessWidget에선 사용 불가)
            () => setState(() => _selectedIndex = _tabController.index));
  }

  @override
  void dispose(){ // 앱 종료 시, 자원들 삭제
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Test App"),
      ),
      // 앱 하단 아이콘 별 클릭 시, 화면 전환이 '스르륵'
      body: TabBarView(   // TabBarView : TabController 와 연결되는 페이지 전환 위젯
        controller: _tabController,
        children: [
          tabContainer(context, Colors.indigo, "Friends Tab"),
          tabContainer(context, Colors.amber, "Chats Tab"),
          tabContainer(context, Colors.blueGrey, "Settings Tab"),
        ],
      ),
      bottomNavigationBar: SizedBox(
        height: 80,
        child: TabBar(    // TabBar : TabController 와 연결되는 탭 버튼 담당 위젯
            controller: _tabController,
            indicator: BoxDecoration(),	// indicator 없애기
            labelStyle: TextStyle(fontSize: 12,),
            labelColor: Colors.black, // TabBar의 tabs 요소 내의 디폴트는 흰색 글씨라서 변경 필요
            tabs: [
              Tab(
                  icon: Icon(_selectedIndex == 0 ? Icons.person : Icons.person_outline),
                  text: "Friends"
              ),
              Tab(
                  icon: Icon(_selectedIndex == 1 ? Icons.chat : Icons.chat_outlined),
                  text: "Chats"
              ),
              Tab(
                  icon: Icon(_selectedIndex == 2 ? Icons.settings : Icons.settings_outlined),
                  text: "Settings"
              ),
            ]
        ),
      ),
    );
  }

  Widget tabContainer(BuildContext con, Color tabColor, String tabText){
    return Container(
        width: MediaQuery.of(con).size.width, // con : 해당 메소드가 사용된 위젯
        height: MediaQuery.of(con).size.height,
        color: tabColor,
        child: Center(
            child: Text(
                tabText,
                style: TextStyle(
                  color: Colors.white,
                )
            )
        )
    );
  }
}

 

+ Recent posts