플러터:화면 전환(화면 쌓기, 하단 네비게이션 바)(화면 쌓기, 하단 네비게이션 바)

학교의 모든 지식. SMwiki
둘러보기로 이동 검색으로 이동

틀:플러터 Dart:개요 플러터에 대한 지식 분류

  1. 플러터:개요
    1. 플러터:VSCode
  2. 플러터:실행
  3. 개념 잡기
    1. 플러터:화면 하나 만들기
    2. 플러터:변하는 화면(StatefulWidget)
    3. 플러터:화면 전환(화면 쌓기, 하단 네비게이션 바)
    4. 플러터:화면 전환(Drawer)
    5. 플러터:키보드 입력
    6. 플러터:슬라이더
    7. 플러터:그래프 그리기(fl chart)
    8. 플러터:데이터 저장(간단한 데이터)
    9. 플러터:인증(Firebase 인증)
    10. 플러터:인증(OAuth2)
  4. 권한 사용
    1. 플러터:마이크 입력
  5. 위젯
    1. 플러터:아이콘
    2. 플러터:레이아웃 계열 위젯
    3. 플러터:네비게이션 계열 위젯
    4. 플러터:버튼
    5. 플러터:상태관리
  6. 플러터:DB연결
    1. 플러터:Firebase
    2. 플러터:MySQL
  7. 디자인
    1. 플러터:테마
    2. 플러터:앱바
    3. 플러터:버튼
  8. 플러터:배포
  9. 플러터:참고자료
  10. 플러터:위젯
    1. 플러터:공간배치용 위젯
  11. 플러터:라이브러리
    1. 플러터:logger

개요[편집 | 원본 편집]

네이게이션을 통한 화면전환.

기본적으로 네비게이션바로 구조를 잡고, 네비게이터로 상세 화면을 다루는 형식을 많이 쓴다.

기본 화면 전환(Navigator)[편집 | 원본 편집]

  • Flutter 앱에서 화면을 이동하는 가장 기본적인 방식은 Navigator를 사용하는 것이다.
  • Navigator는 “화면(stack)”을 관리하며, 새로운 페이지를 push하여 화면을 열고 pop하여 닫는다.
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Navigator Demo',
      debugShowCheckedModeBanner: false,
      home: FirstPage(),
    );
  }
}

class FirstPage extends StatelessWidget {
  // StatelessWidget: 상태(state)를 가지지 않는 화면
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("첫 번째 화면"),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text("두 번째 화면으로 이동"),
          onPressed: () {
            // 화면 이동 (push)
            Navigator.push(
              context,
              MaterialPageRoute(builder: (_) => SecondPage()),
            );
          },
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  // 두 번째 화면도 상태를 가지지 않는 StatelessWidget
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("두 번째 화면"),
      ),
      body: Center(
        child: Text(
          "여기는 두 번째 화면!",
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }
}

이해를 위한 추가 설명[편집 | 원본 편집]

요소 설명 비고
화면을 위에 올리기.

Navigator.push

Navigator.push(
context,
MaterialPageRoute(builder: (_) => SecondPage()),
);

새로운 페이지를 스택 위에 ‘올려서’ 이동한다.

MaterialPageRoute는 기본적인 화면 전환 애니메이션을 제공한다.

마테리얼 디자인 규칙에 따라 뒤로가기가 가능하면 자동으로 뒤로가기 버튼이 생긴다.
뒤로 가기

Navigator.pop

Navigator.pop(context)

현재 페이지를 스택에서 제거(pop)하여 이전 화면으로 돌아간다.

결론[편집 | 원본 편집]

스택을 쌓아 화면이 바뀐다.

의문[편집 | 원본 편집]

왜 push()는 context가 필요한가?[편집 | 원본 편집]

Navigator는 위젯 트리 안에 존재하는 “Navigator State”를 찾아야 하는데, 이를 위해 현재 위젯의 BuildContext가 필요하다.

BuildContext는 “현재 위젯이 트리에서 어디 위치하는지”를 나타내는 정보다.

MaterialPageRoute 말고 다른 것도 있나?[편집 | 원본 편집]

있다.

  • CupertinoPageRoute (iOS 스타일 전환)
  • PageRouteBuilder (전환 애니메이션 직접 커스텀)
  • go_router, auto_route 같은 라우팅 라이브러리

기본 예제는 MaterialPageRoute로 충분하다.

기본 하단 네비게이션 바[편집 | 원본 편집]

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'BottomNavigation Demo',
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _selectedIndex = 0; // 현재 선택된 탭

  // 탭마다 보여줄 화면
  static const List<Widget> _pages = <Widget>[
    Center(
      child: Text(
        '첫 번째 화면',
        style: TextStyle(fontSize: 24),
      ),
    ),
    Center(
      child: Text(
        '두 번째 화면',
        style: TextStyle(fontSize: 24),
      ),
    ),
    Center(
      child: Text(
        '세 번째 화면',
        style: TextStyle(fontSize: 24),
      ),
    ),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index; // 탭 선택 시 상태 변경
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('BottomNavigationBar Demo'),
      ),
      body: _pages[_selectedIndex], // 현재 선택된 화면 표시
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedIndex,
        onTap: _onItemTapped, // 탭 클릭 시 호출
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: '홈',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            label: '비즈니스',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            label: '학교',
          ),
        ],
      ),
    );
  }
}

이해를 위한 추가 설명[편집 | 원본 편집]

요소 설명 비고
_onItemTapped 탭 클릭 시 호출되는 함수.

자동으로 Index가 입력된다.

BottomNavigationBarType 옵션은?
  • fixed: 모든 탭이 항상 같은 너비로 표시
  • shifting: 선택된 탭 강조, 배경색 변화 가능

기본값은 탭이 3개 이상이면 fixed, 3개 이하이면 shifting

기본값은 아래 옵션으로 바꾸어 지정 가능.

  type: BottomNavigationBarType.fixed, // 고정형

shifting이면 각 탭에 색을 넣어주어야 한다.

backgroundColor: Colors.blue, 형태로.

의문[편집 | 원본 편집]

StatelessWidget으로도 만들 수 없나?[편집 | 원본 편집]

탭 선택 상태를 저장할 방법이 없으므로 일반 StatelessWidget으로는 불가능하다. 탭 상태를 유지하면서 화면 전환하려면 StatefulWidget을 사용해야 한다.