개발노트

6. [Flutter] 앱 하단에 화면전환 버튼 만들기(with BottomNavigationBar) 본문

앱 개발/Flutter

6. [Flutter] 앱 하단에 화면전환 버튼 만들기(with BottomNavigationBar)

mroh1226 2023. 3. 30. 16:14
반응형

BottomNavigationBar 을 사용하여 화면 하단에 Tap 버튼을 두고 위젯(화면)을 전환시키는 기능을 만들어 보겠습니다.

 

전환되는 화면으로 사용할 Widget을 views라는 폴더를 두고 각각 생성해 줬습니다.

 

전환되는 것만 확인할 거라서 Text('화면명') 위젯만 추가하였습니다.

views 폴더에 page로 사용할 widget 추가


main.dart
import 'package:flutter/material.dart';
import 'package:flutter_tonetrainer/views/page_dump.dart';
import 'package:flutter_tonetrainer/views/page_reward.dart';
import 'package:flutter_tonetrainer/views/page_theory.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'MyApp',
      home: HomePage(),
    );
  }
}

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int selectedIndex = 0;
  final List<Widget> pages = [
    const PageDump(),
    const PageTheory(),
    const PageReward()
  ];
  void btnClick(int index) {
    setState(() {
      selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: pages[selectedIndex],
      bottomNavigationBar: BottomNavigationBar(
        iconSize: 30,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.list), label: 'Dump'),
          BottomNavigationBarItem(icon: Icon(Icons.book), label: 'Theory'),
          BottomNavigationBarItem(
              icon: Icon(Icons.workspace_premium_sharp), label: 'Reward')
        ],
        currentIndex: selectedIndex,
        onTap: btnClick,
      ),
    );
  }
}

 

 

설명

버튼을 클릭했을 때 HomePage 위젯에 화면으로 사용될 위젯들로 디자인을 새로해야하기 때문에 setState()가 필요하여  StatefulWidget을 사용하였습니다.

 int selectedIndex = 0;
  final List<Widget> pages = [
    const PageDump(),
    const PageTheory(),
    const PageReward()
  ];

Widget을 item으로 갖는 List pages를 생성하고 각각의 Page 클래스들을 넣어줬습니다.

선택한 버튼의 index를 저장할 selectedIndex를 선언하고 0으로 초기화 시켜줍니다.

 

Widget build(BuildContext context) {
    return Scaffold(
      body: pages[selectedIndex],
      bottomNavigationBar: BottomNavigationBar(
        iconSize: 30,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.list), label: 'Dump'),
          BottomNavigationBarItem(icon: Icon(Icons.book), label: 'Theory'),
          BottomNavigationBarItem(
              icon: Icon(Icons.workspace_premium_sharp), label: 'Reward')
        ],
        currentIndex: selectedIndex,
        onTap: btnClick,
      ),
    );
  }

Scaffold의 body에 pages[SelectedIndex] 위젯을 넣어 선택된 Page를 바디에 생성합니다.

(위에서 selectedIndex0으로 초기화했기 때문에 PageDump()가 초기화면에 생성됩니다.)

 

Scaffold가 제공하는 bottomNavigationBar: 속성에 BottomNavigationBar() 위젯을 생성하고 

BottomNavigationBar()의 items: 속성에 BottomNavigationBarItem을 3개 넣어줍니다.(3개의 Page)

BottomNavigationBar는 여러 개의 BottomNavigationBarItem 위젯을 가지며, 각 아이템은 아이콘과 라벨을 포함합니다.

 

 void btnClick(int index) {
    setState(() {
      selectedIndex = index;
    });
  }

currentIndex는 현재 선택된 BottomNavigationBarItem의 인덱스를 가리키며, currentIndex를 selectedIndex로 지정하여 업데이트 시키고, onTap: 에 설정된 btnClick(int index)이벤트 핸들러를 통해 아이템이 선택될 때마다 index가 업데이트되어 Page가 보여집니다.


즉, selectedIndex 변수는 현재 선택된 페이지를 나타내며, 이 변수를 사용하여 pages 배열에서 해당 페이지를 가져와서 Scaffold 위젯의 body 속성에 전달합니다. 따라서 BottomNavigationBar에서 선택된 아이템에 따라 보여지는 페이지가 변경됩니다.


전환화면 3개 소스코드

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

class PageDump extends StatelessWidget {
  const PageDump({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
        body: Center(
      child: Text('PageDump'),
    ));
  }
}

 

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

class PageReward extends StatelessWidget {
  const PageReward({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(
        child: Text('PageReward'),
      ),
    );
  }
}

 

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

class PageTheory extends StatelessWidget {
  const PageTheory({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
        body: Center(
      child: Text('PageTheory'),
    ));
  }
}

[빌드된 모습]

 

반응형
Comments