본문으로 바로가기
  1. Home
  2. Flutter/Widget
  3. Flutter bottomNavigationBar (상태유지) 문서

Flutter bottomNavigationBar (상태유지) 문서

· 댓글개 · Dev_Whale

사용되는 위젯목록

  • TabController
  • DefaultTabController
  • TabBarView
  • TabBar
  • Tab
  • TickerProviderStateMixin
  • AutomaticKeepAliveClientMixin
    • bool get wantKeepAlive => true;
    • super.build(context);

1. with TickerProviderStateMixin 추가

class _BottomNavigationBarScreenState extends State<BottomNavigationBarScreen>
    with TickerProviderStateMixin 

2. TabController 추가

  • animationDuration 프로퍼티 존재
_tabController = TabController(length: 3, vsync: this, initialIndex: 0);

animationDuration 3초 적용

3.Scaffold를 DefaultTabController로 Wrap 하기

Widget build(BuildContext context) {
  return DefaultTabController(
    length: 3,
    child: Scaffold(...),
  );
}

4. Scaffold - body - TabBarView 추가

child: Scaffold(
  body: TabBarView(
    controller: _tabController,
    children: [
      DemoScreen(title: 'First'),
      DemoScreen(title: 'Second'),
      DemoScreen(title: 'Third'),
    ],
  ),

 5. Scaffold - bottomNavigationBar - TabBar 추가

bottomNavigationBar: TabBar(
  controller: _tabController,
  indicator: BoxDecoration(
    border: Border(
      top: BorderSide(width: 3.5, color: Theme.of(context).indicatorColor),
    ),
  ),
  tabs: [
    Tab(
      icon: Icon(
        Icons.calculate_outlined,
        color: Colors.black,
      ),
      iconMargin: const EdgeInsets.only(bottom: 2),
      child: Text(
        'Name1',
        style: TextStyle(color: Colors.black),
      ),
    ),
    ...
  ],
),

6. length 만큼 Tab 추가

Tab(
  icon: Icon(
    Icons.calculate_outlined,
    color: Colors.black,
  ),
  iconMargin: const EdgeInsets.only(bottom: 2),
  child: Text(
    'Name1',
    style: TextStyle(color: Colors.black),
  ),
),

이 까지가 상태 유지 없는 BottomNavigationBar이다 == Tab 할 때마다 해당 페이지 rebuild 된다는 말이다.


Keep State

1. TabBarView에 추가한 각 페이지에 AutomaticKeepAliveClientMixin을 추가

class _DemoScreenState extends State<DemoScreen> with AutomaticKeepAliveClientMixin {

2. get 키워드를 추가

@override
bool get wantKeepAlive => true;

3. super.build(context); 추가

@override
Widget build(BuildContext context) {
  super.build(context); // Add line

Full Source Code (더보기 클릭)

더보기

main.dart

import 'package:flutter/material.dart';
import 'package:test_app/screen.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: BottomNavigationBarScreen(),
    );
  }
}

class BottomNavigationBarScreen extends StatefulWidget {
  @override
  State<BottomNavigationBarScreen> createState() => _BottomNavigationBarScreenState();
}

class _BottomNavigationBarScreenState extends State<BottomNavigationBarScreen>
    with TickerProviderStateMixin {
  late TabController _tabController;

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

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        body: TabBarView(
          controller: _tabController,
          children: [
            DemoScreen(title: 'First'),
            DemoScreen(title: 'Second'),
            DemoScreen(title: 'Third'),
          ],
        ),
        bottomNavigationBar: TabBar(
          controller: _tabController,
          indicatorWeight: 20,
          indicator: BoxDecoration(
            border: Border(
              top: BorderSide(width: 3.5, color: Theme.of(context).indicatorColor),
            ),
          ),
          tabs: [
            Tab(
              icon: Icon(
                Icons.calculate_outlined,
                color: Colors.black,
              ),
              iconMargin: const EdgeInsets.only(bottom: 2),
              child: Text(
                'Name1',
                style: TextStyle(color: Colors.black),
              ),
            ),
            Tab(
              icon: Icon(
                Icons.calculate_outlined,
                color: Colors.black,
              ),
              iconMargin: const EdgeInsets.only(bottom: 2),
              child: Text(
                'Name2',
                style: TextStyle(color: Colors.black),
              ),
            ),
            Tab(
              icon: Icon(
                Icons.calculate_outlined,
                color: Colors.black,
              ),
              iconMargin: const EdgeInsets.only(bottom: 2),
              child: Text(
                'Name3',
                style: TextStyle(color: Colors.black),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

screen.dart

import 'package:flutter/material.dart';

class DemoScreen extends StatefulWidget {
  final String title;

  DemoScreen({required this.title});

  @override
  State<DemoScreen> createState() => _DemoScreenState();
}

class _DemoScreenState extends State<DemoScreen> with AutomaticKeepAliveClientMixin {

  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Scaffold(
      appBar: AppBar(title: Text(widget.title + " AppBar"),),
      body: Center(
        child: Text(widget.title),
      ),
    );
  }
}

'Flutter > Widget' 카테고리의 다른 글

Flutter TextFormField 문서  (0) 2022.05.05
Flutter DateTime Method 문서 [7/13 보완 작성하기]  (0) 2022.05.04
Flutter Stepper widget 문서  (0) 2022.05.02
Flutter ListTile 프로퍼티 문서  (0) 2021.05.22
Flutter ExpansionPanel 문서  (0) 2021.05.14
최근 글
Dev_Whale의 Flutter 블로그
추천하는 글
Dev_Whale의 Flutter 블로그
💬 댓글 개
이모티콘창 닫기
울음
안녕
감사해요
당황
피폐

이모티콘을 클릭하면 댓글창에 입력됩니다.